@codeyam/codeyam-cli 0.1.0-staging.8e7b1bd → 0.1.0-staging.b8a55ba
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/package.json +1 -1
- package/analyzer-template/packages/ai/src/lib/analyzeScope.ts +2 -0
- package/analyzer-template/packages/ai/src/lib/astScopes/astScopeAnalyzer.ts +22 -0
- package/analyzer-template/packages/ai/src/lib/astScopes/patterns/switchStatementHandler.ts +23 -1
- package/analyzer-template/packages/ai/src/lib/astScopes/processExpression.ts +401 -106
- package/analyzer-template/packages/ai/src/lib/astScopes/types.ts +60 -0
- package/analyzer-template/packages/ai/src/lib/dataStructure/ScopeDataStructure.ts +661 -50
- package/analyzer-template/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/JavascriptFrameworkManager.ts +14 -2
- package/analyzer-template/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/MuiManager.ts +715 -0
- package/analyzer-template/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/ReactFrameworkManager.ts +123 -1
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.ts +19 -1
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/cleanNonObjectFunctions.ts +23 -1
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/convertDotNotation.ts +23 -0
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.ts +34 -1
- package/analyzer-template/packages/ai/src/lib/gatherRelevantDependentKeyAttributes.ts +236 -24
- package/analyzer-template/packages/ai/src/lib/generateChangesEntityKeyAttributes.ts +18 -1
- package/analyzer-template/packages/ai/src/lib/generateChangesEntityScenarios.ts +37 -4
- package/analyzer-template/packages/ai/src/lib/generateEntityDataStructure.ts +5 -0
- package/analyzer-template/packages/ai/src/lib/generateEntityKeyAttributes.ts +213 -12
- package/analyzer-template/packages/ai/src/lib/generateEntityScenarioData.ts +11 -15
- package/analyzer-template/packages/ai/src/lib/generateEntityScenarios.ts +114 -11
- package/analyzer-template/packages/ai/src/lib/getConditionalUsagesFromCode.ts +143 -31
- package/analyzer-template/packages/ai/src/lib/guessScenarioDataFromDescription.ts +8 -2
- package/analyzer-template/packages/ai/src/lib/promptGenerators/gatherAttributesMap.ts +7 -0
- package/analyzer-template/packages/ai/src/lib/promptGenerators/generateChangesEntityScenariosGenerator.ts +42 -2
- package/analyzer-template/packages/ai/src/lib/promptGenerators/generateEntityScenariosGenerator.ts +38 -2
- package/analyzer-template/packages/ai/src/lib/promptGenerators/guessNewScenarioDataFromDescriptionGenerator.ts +28 -2
- package/analyzer-template/packages/ai/src/lib/worker/SerializableDataStructure.ts +5 -0
- package/analyzer-template/packages/ai/src/lib/worker/analyzeScopeWorker.ts +8 -1
- package/analyzer-template/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.ts +339 -145
- package/analyzer-template/packages/analyze/src/lib/files/analyze/analyzeEntities.ts +20 -0
- package/analyzer-template/packages/analyze/src/lib/files/getImportedExports.ts +8 -1
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/enrichArrayTypesFromChildSignatures.ts +158 -0
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.ts +107 -18
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateChangesScenarioData.ts +1 -1
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateDataStructure.ts +223 -103
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateKeyAttributes.ts +10 -5
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateScenarioData.ts +172 -83
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateScenarios.ts +2 -5
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.ts +97 -27
- package/analyzer-template/packages/aws/dist/src/lib/s3/checkS3ObjectExists.d.ts +15 -0
- package/analyzer-template/packages/aws/dist/src/lib/s3/checkS3ObjectExists.d.ts.map +1 -0
- package/analyzer-template/packages/aws/dist/src/lib/s3/checkS3ObjectExists.js +31 -0
- package/analyzer-template/packages/aws/dist/src/lib/s3/checkS3ObjectExists.js.map +1 -0
- package/analyzer-template/packages/aws/package.json +1 -1
- package/analyzer-template/packages/aws/s3/index.ts +1 -0
- package/analyzer-template/packages/aws/src/lib/s3/checkS3ObjectExists.ts +47 -0
- package/analyzer-template/packages/database/src/lib/kysely/db.ts +4 -4
- package/analyzer-template/packages/database/src/lib/kysely/tableRelations.ts +2 -2
- package/analyzer-template/packages/database/src/lib/kysely/tables/debugReportsTable.ts +20 -9
- package/analyzer-template/packages/database/src/lib/loadReadyToBeCapturedAnalyses.ts +3 -2
- package/analyzer-template/packages/generate/src/lib/componentScenarioPage/getIFrameMessageListenerCode.ts +9 -4
- package/analyzer-template/packages/generate/src/lib/deepMerge.ts +26 -1
- package/analyzer-template/packages/generate/src/lib/getComponentScenarioPath.ts +8 -3
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/db.d.ts +2 -2
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/db.js +2 -2
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/tableRelations.d.ts +2 -2
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/analysesTable.d.ts +8 -1
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/analysesTable.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/debugReportsTable.d.ts +14 -7
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/debugReportsTable.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/debugReportsTable.js +9 -3
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/debugReportsTable.js.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/scenariosTable.d.ts +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/scenariosTable.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/loadReadyToBeCapturedAnalyses.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/loadReadyToBeCapturedAnalyses.js +4 -2
- package/analyzer-template/packages/github/dist/database/src/lib/loadReadyToBeCapturedAnalyses.js.map +1 -1
- package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/getIFrameMessageListenerCode.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/getIFrameMessageListenerCode.js +8 -4
- package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/getIFrameMessageListenerCode.js.map +1 -1
- package/analyzer-template/packages/github/dist/generate/src/lib/deepMerge.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/generate/src/lib/deepMerge.js +27 -1
- package/analyzer-template/packages/github/dist/generate/src/lib/deepMerge.js.map +1 -1
- package/analyzer-template/packages/github/dist/generate/src/lib/getComponentScenarioPath.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/generate/src/lib/getComponentScenarioPath.js +7 -3
- package/analyzer-template/packages/github/dist/generate/src/lib/getComponentScenarioPath.js.map +1 -1
- package/analyzer-template/packages/github/dist/types/index.d.ts +4 -3
- package/analyzer-template/packages/github/dist/types/index.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/types/index.js +1 -0
- package/analyzer-template/packages/github/dist/types/index.js.map +1 -1
- package/analyzer-template/packages/github/dist/types/src/types/Analysis.d.ts +31 -1
- package/analyzer-template/packages/github/dist/types/src/types/Analysis.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/types/src/types/Scenario.d.ts +51 -1
- package/analyzer-template/packages/github/dist/types/src/types/Scenario.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/types/src/types/Scenario.js +21 -1
- package/analyzer-template/packages/github/dist/types/src/types/Scenario.js.map +1 -1
- package/analyzer-template/packages/github/dist/types/src/types/ScenariosDataStructure.d.ts +48 -0
- package/analyzer-template/packages/github/dist/types/src/types/ScenariosDataStructure.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/utils/src/lib/applyUniversalMocks.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/utils/src/lib/applyUniversalMocks.js +26 -2
- package/analyzer-template/packages/github/dist/utils/src/lib/applyUniversalMocks.js.map +1 -1
- package/analyzer-template/packages/github/dist/utils/src/lib/lightweightEntityExtractor.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/utils/src/lib/lightweightEntityExtractor.js +25 -0
- package/analyzer-template/packages/github/dist/utils/src/lib/lightweightEntityExtractor.js.map +1 -1
- package/analyzer-template/packages/types/index.ts +8 -0
- package/analyzer-template/packages/types/src/types/Analysis.ts +32 -1
- package/analyzer-template/packages/types/src/types/Scenario.ts +75 -6
- package/analyzer-template/packages/types/src/types/ScenariosDataStructure.ts +49 -0
- package/analyzer-template/packages/ui-components/package.json +4 -4
- package/analyzer-template/packages/ui-components/src/components/ScenarioDetailInteractiveView.tsx +23 -7
- package/analyzer-template/packages/utils/dist/types/index.d.ts +4 -3
- package/analyzer-template/packages/utils/dist/types/index.d.ts.map +1 -1
- package/analyzer-template/packages/utils/dist/types/index.js +1 -0
- package/analyzer-template/packages/utils/dist/types/index.js.map +1 -1
- package/analyzer-template/packages/utils/dist/types/src/types/Analysis.d.ts +31 -1
- package/analyzer-template/packages/utils/dist/types/src/types/Analysis.d.ts.map +1 -1
- package/analyzer-template/packages/utils/dist/types/src/types/Scenario.d.ts +51 -1
- package/analyzer-template/packages/utils/dist/types/src/types/Scenario.d.ts.map +1 -1
- package/analyzer-template/packages/utils/dist/types/src/types/Scenario.js +21 -1
- package/analyzer-template/packages/utils/dist/types/src/types/Scenario.js.map +1 -1
- package/analyzer-template/packages/utils/dist/types/src/types/ScenariosDataStructure.d.ts +48 -0
- package/analyzer-template/packages/utils/dist/types/src/types/ScenariosDataStructure.d.ts.map +1 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/applyUniversalMocks.d.ts.map +1 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/applyUniversalMocks.js +26 -2
- package/analyzer-template/packages/utils/dist/utils/src/lib/applyUniversalMocks.js.map +1 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/lightweightEntityExtractor.d.ts.map +1 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/lightweightEntityExtractor.js +25 -0
- package/analyzer-template/packages/utils/dist/utils/src/lib/lightweightEntityExtractor.js.map +1 -1
- package/analyzer-template/packages/utils/src/lib/applyUniversalMocks.ts +28 -2
- package/analyzer-template/packages/utils/src/lib/lightweightEntityExtractor.ts +27 -0
- package/analyzer-template/playwright/takeElementScreenshot.ts +26 -11
- package/analyzer-template/playwright/takeScreenshot.ts +9 -7
- package/analyzer-template/project/TESTING.md +83 -0
- package/analyzer-template/project/constructMockCode.ts +151 -30
- package/analyzer-template/project/loadReadyToBeCaptured.ts +17 -1
- package/analyzer-template/project/orchestrateCapture/KyselyAnalysisLoader.ts +16 -9
- package/analyzer-template/project/orchestrateCapture/SequentialCaptureTaskRunner.ts +77 -37
- package/analyzer-template/project/reconcileMockDataKeys.ts +104 -3
- package/analyzer-template/project/runMultiScenarioServer.ts +11 -10
- package/analyzer-template/project/serverOnlyModules.ts +288 -0
- package/analyzer-template/project/start.ts +10 -0
- package/analyzer-template/project/startScenarioCapture.ts +73 -41
- package/analyzer-template/project/writeMockDataTsx.ts +103 -40
- package/analyzer-template/project/writeScenarioComponents.ts +1162 -203
- package/analyzer-template/project/writeSimpleRoot.ts +26 -4
- package/analyzer-template/project/writeUniversalMocks.ts +32 -11
- package/background/src/lib/virtualized/project/constructMockCode.js +132 -25
- package/background/src/lib/virtualized/project/constructMockCode.js.map +1 -1
- package/background/src/lib/virtualized/project/loadReadyToBeCaptured.js +15 -1
- package/background/src/lib/virtualized/project/loadReadyToBeCaptured.js.map +1 -1
- package/background/src/lib/virtualized/project/orchestrateCapture/KyselyAnalysisLoader.js +11 -6
- package/background/src/lib/virtualized/project/orchestrateCapture/KyselyAnalysisLoader.js.map +1 -1
- package/background/src/lib/virtualized/project/orchestrateCapture/SequentialCaptureTaskRunner.js +67 -32
- package/background/src/lib/virtualized/project/orchestrateCapture/SequentialCaptureTaskRunner.js.map +1 -1
- package/background/src/lib/virtualized/project/reconcileMockDataKeys.js +65 -4
- package/background/src/lib/virtualized/project/reconcileMockDataKeys.js.map +1 -1
- package/background/src/lib/virtualized/project/runMultiScenarioServer.js +11 -9
- package/background/src/lib/virtualized/project/runMultiScenarioServer.js.map +1 -1
- package/background/src/lib/virtualized/project/serverOnlyModules.js +235 -0
- package/background/src/lib/virtualized/project/serverOnlyModules.js.map +1 -0
- package/background/src/lib/virtualized/project/start.js +6 -0
- package/background/src/lib/virtualized/project/start.js.map +1 -1
- package/background/src/lib/virtualized/project/startScenarioCapture.js +54 -31
- package/background/src/lib/virtualized/project/startScenarioCapture.js.map +1 -1
- package/background/src/lib/virtualized/project/writeMockDataTsx.js +87 -34
- package/background/src/lib/virtualized/project/writeMockDataTsx.js.map +1 -1
- package/background/src/lib/virtualized/project/writeScenarioComponents.js +852 -133
- package/background/src/lib/virtualized/project/writeScenarioComponents.js.map +1 -1
- package/background/src/lib/virtualized/project/writeSimpleRoot.js +25 -2
- package/background/src/lib/virtualized/project/writeSimpleRoot.js.map +1 -1
- package/background/src/lib/virtualized/project/writeUniversalMocks.js +27 -12
- package/background/src/lib/virtualized/project/writeUniversalMocks.js.map +1 -1
- package/codeyam-cli/scripts/fixtures/formbricks/universal-mocks/apps/web/lib/instance/service.js +7 -0
- package/codeyam-cli/scripts/fixtures/formbricks/universal-mocks/apps/web/lib/instance/service.js.map +1 -0
- package/codeyam-cli/src/cli.js +2 -0
- package/codeyam-cli/src/cli.js.map +1 -1
- package/codeyam-cli/src/commands/debug.js +14 -2
- package/codeyam-cli/src/commands/debug.js.map +1 -1
- package/codeyam-cli/src/commands/recapture.js +215 -0
- package/codeyam-cli/src/commands/recapture.js.map +1 -0
- package/codeyam-cli/src/commands/report.js +26 -23
- package/codeyam-cli/src/commands/report.js.map +1 -1
- package/codeyam-cli/src/utils/backgroundServer.js +2 -2
- package/codeyam-cli/src/utils/backgroundServer.js.map +1 -1
- package/codeyam-cli/src/utils/generateReport.js +252 -106
- package/codeyam-cli/src/utils/generateReport.js.map +1 -1
- package/codeyam-cli/src/utils/install-skills.js +2 -7
- package/codeyam-cli/src/utils/install-skills.js.map +1 -1
- package/codeyam-cli/src/utils/queue/__tests__/manager.test.js +38 -0
- package/codeyam-cli/src/utils/queue/__tests__/manager.test.js.map +1 -1
- package/codeyam-cli/src/utils/queue/job.js +140 -16
- package/codeyam-cli/src/utils/queue/job.js.map +1 -1
- package/codeyam-cli/src/utils/queue/manager.js +19 -7
- package/codeyam-cli/src/utils/queue/manager.js.map +1 -1
- package/codeyam-cli/src/utils/queue/persistence.js.map +1 -1
- package/codeyam-cli/src/webserver/app/lib/database.js +47 -0
- package/codeyam-cli/src/webserver/app/lib/database.js.map +1 -1
- package/codeyam-cli/src/webserver/app/lib/dbNotifier.js.map +1 -1
- package/codeyam-cli/src/webserver/backgroundServer.js +5 -10
- package/codeyam-cli/src/webserver/backgroundServer.js.map +1 -1
- package/codeyam-cli/src/webserver/bootstrap.js +9 -0
- package/codeyam-cli/src/webserver/bootstrap.js.map +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/EntityItem-wXL1Z2Aq.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{EntityTypeBadge-DQeyk25_.js → EntityTypeBadge-CzGX-miz.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/EntityTypeIcon-CXFKsCOD.js +41 -0
- package/codeyam-cli/src/webserver/build/client/assets/InteractivePreview-D-9pXIaY.js +25 -0
- package/codeyam-cli/src/webserver/build/client/assets/LibraryFunctionPreview-CBQPrpT0.js +3 -0
- package/codeyam-cli/src/webserver/build/client/assets/LoadingDots-D1CdlbrV.js +6 -0
- package/codeyam-cli/src/webserver/build/client/assets/LogViewer-wDPcZNKx.js +3 -0
- package/codeyam-cli/src/webserver/build/client/assets/ReportIssueModal-4lcOlid-.js +11 -0
- package/codeyam-cli/src/webserver/build/client/assets/SafeScreenshot-BfmDgXxG.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/ScenarioViewer-CUxUNEEC.js +15 -0
- package/codeyam-cli/src/webserver/build/client/assets/{TruncatedFilePath-ayCJdUAc.js → TruncatedFilePath-6J7zDUD5.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/_index-DHImXdXq.js +11 -0
- package/codeyam-cli/src/webserver/build/client/assets/activity.(_tab)-2mG6mjVb.js +32 -0
- package/codeyam-cli/src/webserver/build/client/assets/api.link-scenario-value-l0sNRNKZ.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/api.update-key-attributes-l0sNRNKZ.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/api.update-valid-values-l0sNRNKZ.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/chevron-down-BYimnrHg.js +6 -0
- package/codeyam-cli/src/webserver/build/client/assets/chunk-JMJ3UQ3L-BambyYE_.js +51 -0
- package/codeyam-cli/src/webserver/build/client/assets/circle-check-CaVsIRxt.js +6 -0
- package/codeyam-cli/src/webserver/build/client/assets/createLucideIcon-CgUsG7ib.js +21 -0
- package/codeyam-cli/src/webserver/build/client/assets/cy-logo-cli-CKnwPCDr.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/dev.empty-DW_hdGUc.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{entity._sha._-FHOVOgFN.js → entity._sha._-zUEpfPsu.js} +22 -15
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha.scenarios._scenarioId.fullscreen-DyB90fWk.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.create-scenario-D_3ero5o.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.edit._scenarioId-CfLCUi9S.js +5 -0
- package/codeyam-cli/src/webserver/build/client/assets/entry.client-DKJyZfAY.js +29 -0
- package/codeyam-cli/src/webserver/build/client/assets/fileTableUtils-DAtOlaWE.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/files-ClR0d32A.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/git-D62Lxxmv.js +15 -0
- package/codeyam-cli/src/webserver/build/client/assets/globals-C6vQASxy.css +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/html2canvas-pro.esm-fmIEn3Bc.js +9 -0
- package/codeyam-cli/src/webserver/build/client/assets/index-BosqDOlH.js +3 -0
- package/codeyam-cli/src/webserver/build/client/assets/index-CzNNiTkw.js +9 -0
- package/codeyam-cli/src/webserver/build/client/assets/keyAttributeCoverage-CTlFMihX.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/loader-circle-CNp9QFCX.js +6 -0
- package/codeyam-cli/src/webserver/build/client/assets/manifest-09d684be.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/preload-helper-ckwbz45p.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/root-BxJUvKau.js +56 -0
- package/codeyam-cli/src/webserver/build/client/assets/scenarioStatus-B_8jpV3e.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/search-DDGjYAMJ.js +6 -0
- package/codeyam-cli/src/webserver/build/client/assets/settings-DgTyB-Wg.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/simulations-CoNWGt0K.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/triangle-alert-CBc5dE1s.js +6 -0
- package/codeyam-cli/src/webserver/build/client/assets/useCustomSizes-BMIGFP-m.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/useInteractiveMode-Dk_FQqWJ.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{useLastLogLine-DOGXmJcI.js → useLastLogLine-BqPPNjAl.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/useReportContext-DsJbgMY9.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{useToast-C07gRg7Z.js → useToast-DWHcCcl1.js} +1 -1
- package/codeyam-cli/src/webserver/build/server/assets/index-CV6i1S1A.js +1 -0
- package/codeyam-cli/src/webserver/build/server/assets/server-build-BDlyhfrv.js +175 -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/src/webserver/devServer.js +1 -3
- package/codeyam-cli/src/webserver/devServer.js.map +1 -1
- package/codeyam-cli/templates/debug-codeyam.md +620 -0
- package/package.json +14 -14
- package/packages/ai/src/lib/analyzeScope.js +2 -0
- package/packages/ai/src/lib/analyzeScope.js.map +1 -1
- package/packages/ai/src/lib/astScopes/astScopeAnalyzer.js +16 -0
- package/packages/ai/src/lib/astScopes/astScopeAnalyzer.js.map +1 -1
- package/packages/ai/src/lib/astScopes/patterns/switchStatementHandler.js +16 -0
- package/packages/ai/src/lib/astScopes/patterns/switchStatementHandler.js.map +1 -1
- package/packages/ai/src/lib/astScopes/processExpression.js +305 -88
- package/packages/ai/src/lib/astScopes/processExpression.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js +523 -42
- package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/JavascriptFrameworkManager.js +12 -2
- package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/JavascriptFrameworkManager.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/MuiManager.js +454 -0
- package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/MuiManager.js.map +1 -0
- package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/ReactFrameworkManager.js +103 -1
- package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/ReactFrameworkManager.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.js +16 -1
- package/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/helpers/cleanNonObjectFunctions.js +19 -1
- package/packages/ai/src/lib/dataStructure/helpers/cleanNonObjectFunctions.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/helpers/convertDotNotation.js +20 -0
- package/packages/ai/src/lib/dataStructure/helpers/convertDotNotation.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.js +28 -2
- package/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.js.map +1 -1
- package/packages/ai/src/lib/gatherRelevantDependentKeyAttributes.js +179 -17
- package/packages/ai/src/lib/gatherRelevantDependentKeyAttributes.js.map +1 -1
- package/packages/ai/src/lib/generateChangesEntityKeyAttributes.js +6 -0
- package/packages/ai/src/lib/generateChangesEntityKeyAttributes.js.map +1 -1
- package/packages/ai/src/lib/generateChangesEntityScenarios.js +37 -4
- package/packages/ai/src/lib/generateChangesEntityScenarios.js.map +1 -1
- package/packages/ai/src/lib/generateEntityDataStructure.js +4 -0
- package/packages/ai/src/lib/generateEntityDataStructure.js.map +1 -1
- package/packages/ai/src/lib/generateEntityKeyAttributes.js +176 -9
- package/packages/ai/src/lib/generateEntityKeyAttributes.js.map +1 -1
- package/packages/ai/src/lib/generateEntityScenarioData.js +11 -15
- package/packages/ai/src/lib/generateEntityScenarioData.js.map +1 -1
- package/packages/ai/src/lib/generateEntityScenarios.js +105 -9
- package/packages/ai/src/lib/generateEntityScenarios.js.map +1 -1
- package/packages/ai/src/lib/getConditionalUsagesFromCode.js +84 -14
- package/packages/ai/src/lib/getConditionalUsagesFromCode.js.map +1 -1
- package/packages/ai/src/lib/guessScenarioDataFromDescription.js +2 -1
- package/packages/ai/src/lib/guessScenarioDataFromDescription.js.map +1 -1
- package/packages/ai/src/lib/promptGenerators/gatherAttributesMap.js +6 -0
- package/packages/ai/src/lib/promptGenerators/gatherAttributesMap.js.map +1 -1
- package/packages/ai/src/lib/promptGenerators/generateChangesEntityScenariosGenerator.js +38 -2
- package/packages/ai/src/lib/promptGenerators/generateChangesEntityScenariosGenerator.js.map +1 -1
- package/packages/ai/src/lib/promptGenerators/generateEntityScenariosGenerator.js +38 -2
- package/packages/ai/src/lib/promptGenerators/generateEntityScenariosGenerator.js.map +1 -1
- package/packages/ai/src/lib/promptGenerators/guessNewScenarioDataFromDescriptionGenerator.js +16 -3
- package/packages/ai/src/lib/promptGenerators/guessNewScenarioDataFromDescriptionGenerator.js.map +1 -1
- package/packages/ai/src/lib/worker/SerializableDataStructure.js.map +1 -1
- package/packages/ai/src/lib/worker/analyzeScopeWorker.js +4 -0
- package/packages/ai/src/lib/worker/analyzeScopeWorker.js.map +1 -1
- package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js +258 -110
- package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js.map +1 -1
- package/packages/analyze/src/lib/files/analyze/analyzeEntities.js +18 -0
- package/packages/analyze/src/lib/files/analyze/analyzeEntities.js.map +1 -1
- package/packages/analyze/src/lib/files/getImportedExports.js +6 -1
- package/packages/analyze/src/lib/files/getImportedExports.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/enrichArrayTypesFromChildSignatures.js +125 -0
- package/packages/analyze/src/lib/files/scenarios/enrichArrayTypesFromChildSignatures.js.map +1 -0
- package/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.js +74 -19
- package/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/generateChangesScenarioData.js +1 -1
- package/packages/analyze/src/lib/files/scenarios/generateChangesScenarioData.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/generateDataStructure.js +175 -58
- package/packages/analyze/src/lib/files/scenarios/generateDataStructure.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/generateKeyAttributes.js +10 -5
- package/packages/analyze/src/lib/files/scenarios/generateKeyAttributes.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/generateScenarioData.js +127 -69
- package/packages/analyze/src/lib/files/scenarios/generateScenarioData.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/generateScenarios.js +2 -5
- package/packages/analyze/src/lib/files/scenarios/generateScenarios.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js +74 -23
- package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js.map +1 -1
- package/packages/database/src/lib/kysely/db.js +2 -2
- package/packages/database/src/lib/kysely/tables/debugReportsTable.js +9 -3
- package/packages/database/src/lib/kysely/tables/debugReportsTable.js.map +1 -1
- package/packages/database/src/lib/loadReadyToBeCapturedAnalyses.js +4 -2
- package/packages/database/src/lib/loadReadyToBeCapturedAnalyses.js.map +1 -1
- package/packages/generate/src/lib/componentScenarioPage/getIFrameMessageListenerCode.js +8 -4
- package/packages/generate/src/lib/componentScenarioPage/getIFrameMessageListenerCode.js.map +1 -1
- package/packages/generate/src/lib/deepMerge.js +27 -1
- package/packages/generate/src/lib/deepMerge.js.map +1 -1
- package/packages/generate/src/lib/getComponentScenarioPath.js +7 -3
- package/packages/generate/src/lib/getComponentScenarioPath.js.map +1 -1
- package/packages/types/index.js +1 -0
- package/packages/types/index.js.map +1 -1
- package/packages/types/src/types/Scenario.js +21 -1
- package/packages/types/src/types/Scenario.js.map +1 -1
- package/packages/utils/src/lib/applyUniversalMocks.js +26 -2
- package/packages/utils/src/lib/applyUniversalMocks.js.map +1 -1
- package/packages/utils/src/lib/lightweightEntityExtractor.js +25 -0
- package/packages/utils/src/lib/lightweightEntityExtractor.js.map +1 -1
- package/scripts/finalize-analyzer.cjs +3 -1
- package/codeyam-cli/src/webserver/build/client/assets/EntityItem-CWKV2GEz.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/EntityTypeIcon-D2hFeDeg.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/InteractivePreview-C8K-4kKP.js +0 -26
- package/codeyam-cli/src/webserver/build/client/assets/LibraryFunctionPreview-DgXLv61M.js +0 -3
- package/codeyam-cli/src/webserver/build/client/assets/LogViewer-DFdLQbPS.js +0 -3
- package/codeyam-cli/src/webserver/build/client/assets/ReportIssueModal-DlRDjT4h.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/SafeScreenshot-7UkVL-UI.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/ScenarioViewer-XjtsGuPo.js +0 -5
- package/codeyam-cli/src/webserver/build/client/assets/_index-D2eJjWLf.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/activity.(_tab)-w6sbwlOd.js +0 -7
- package/codeyam-cli/src/webserver/build/client/assets/chevron-down-BBNQ8hup.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/chunk-WWGJGFF6-Bex4RrGs.js +0 -26
- package/codeyam-cli/src/webserver/build/client/assets/circle-check-cdhjVtom.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/createLucideIcon-DkgmwwRC.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/dev.empty-CwLmCS0J.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.create-scenario-YZ-kM3ZG.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.edit._scenarioId-BeQlz94_.js +0 -5
- package/codeyam-cli/src/webserver/build/client/assets/entry.client-DN2XXM7Z.js +0 -5
- package/codeyam-cli/src/webserver/build/client/assets/fileTableUtils-CUeAIQNI.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/files-ccMQfhGf.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/git-JmESAHx5.js +0 -12
- package/codeyam-cli/src/webserver/build/client/assets/globals-CO-U8Bpo.css +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/html2canvas-pro.esm-XQCGvadH.js +0 -5
- package/codeyam-cli/src/webserver/build/client/assets/index-DsL9BiOc.js +0 -8
- package/codeyam-cli/src/webserver/build/client/assets/loader-circle-COYCR2oZ.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/manifest-90adba57.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/root-DfbVEEjF.js +0 -16
- package/codeyam-cli/src/webserver/build/client/assets/search-DvK9iMBu.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/server-build-CMKNK2uU.css +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/settings-9LTbit4Z.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/simulations-BrxN5ZtV.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/triangle-alert-Iv0p8T-1.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/useReportContext-BWmSRPH6.js +0 -1
- package/codeyam-cli/src/webserver/build/server/assets/index-CE_1qXCG.js +0 -1
- package/codeyam-cli/src/webserver/build/server/assets/server-build-BY_VDhiD.js +0 -166
- package/codeyam-cli/templates/debug-command.md +0 -141
- /package/codeyam-cli/src/webserver/build/client/assets/{InteractivePreview-CMKNK2uU.css → styles-CMKNK2uU.css} +0 -0
|
@@ -221,6 +221,22 @@ export interface FunctionCallInfo {
|
|
|
221
221
|
* For example: { "db.select(query1)": "result1", "db.select(query2)": "result2" }
|
|
222
222
|
*/
|
|
223
223
|
callSignatureToVariable?: Record<string, string>;
|
|
224
|
+
/**
|
|
225
|
+
* Stores individual schemas per call signature BEFORE merging.
|
|
226
|
+
* When multiple calls to the same function are merged into one FunctionCallInfo,
|
|
227
|
+
* this preserves each call's distinct schema.
|
|
228
|
+
* Key is the call signature (e.g., "useFetcher()").
|
|
229
|
+
* Used internally; converted to perVariableSchemas in toSerializable().
|
|
230
|
+
*/
|
|
231
|
+
perCallSignatureSchemas?: Record<string, Record<string, string>>;
|
|
232
|
+
/**
|
|
233
|
+
* Stores individual return value schemas per receiving variable, BEFORE merging.
|
|
234
|
+
* When multiple calls to the same function have different return types
|
|
235
|
+
* (e.g., useFetcher<UserData>() vs useFetcher<ReportData>()), this preserves
|
|
236
|
+
* each call's distinct schema for mock data generation.
|
|
237
|
+
* Key is the receiving variable name (e.g., "userFetcher", "reportFetcher").
|
|
238
|
+
*/
|
|
239
|
+
perVariableSchemas?: Record<string, Record<string, string>>;
|
|
224
240
|
}
|
|
225
241
|
|
|
226
242
|
/**
|
|
@@ -320,6 +336,10 @@ const ALLOWED_EQUIVALENCY_REASONS = new Set([
|
|
|
320
336
|
'propagated function call return sub-property equivalency',
|
|
321
337
|
'propagated parent-variable equivalency', // Added: propagate child scope equivalencies to parent scope when variable is defined in parent
|
|
322
338
|
'where was this function called from', // Added: tracks which scope called an external function
|
|
339
|
+
'MUI DataGrid renderCell params.row equivalency', // Added: links DataGrid renderCell params.row to rows array elements
|
|
340
|
+
'MUI Autocomplete getOptionLabel option equivalency', // Added: links Autocomplete getOptionLabel callback param to options array
|
|
341
|
+
'MUI Autocomplete renderOption option equivalency', // Added: links Autocomplete renderOption callback param to options array
|
|
342
|
+
'MUI Autocomplete option property equivalency', // Added: propagates property accesses from Autocomplete callbacks
|
|
323
343
|
]);
|
|
324
344
|
|
|
325
345
|
const SILENTLY_IGNORED_EQUIVALENCY_REASONS = new Set([
|
|
@@ -382,6 +402,10 @@ export class ScopeDataStructure {
|
|
|
382
402
|
private externalFunctionCallsIndex: Map<string, FunctionCallInfo> | null =
|
|
383
403
|
null;
|
|
384
404
|
|
|
405
|
+
// Tracks internal functions that have been filtered out during captureCompleteSchema
|
|
406
|
+
// Prevents re-adding them via subsequent equivalency propagation (e.g., from getReturnValue)
|
|
407
|
+
private filteredInternalFunctions: Set<string> = new Set();
|
|
408
|
+
|
|
385
409
|
// Debug tracer for selective path/scope tracing
|
|
386
410
|
// Enable via: CODEYAM_DEBUG=true CODEYAM_DEBUG_PATHS="user.*,signature" npm test
|
|
387
411
|
private tracer: DebugTracer = new DebugTracer({
|
|
@@ -540,6 +564,8 @@ export class ScopeDataStructure {
|
|
|
540
564
|
const efcName = this.pathManager.stripGenerics(efc.name);
|
|
541
565
|
for (const manager of this.equivalencyManagers) {
|
|
542
566
|
if (manager.internalFunctions.has(efcName)) {
|
|
567
|
+
// Track this so we don't re-add it via subsequent finalize calls
|
|
568
|
+
this.filteredInternalFunctions.add(efcName);
|
|
543
569
|
return false;
|
|
544
570
|
}
|
|
545
571
|
}
|
|
@@ -567,13 +593,51 @@ export class ScopeDataStructure {
|
|
|
567
593
|
const baseName = this.pathManager.stripGenerics(
|
|
568
594
|
candidate.scopeNodeName,
|
|
569
595
|
);
|
|
596
|
+
// Check if this is a local variable path (doesn't contain function call pattern)
|
|
597
|
+
// Local variables like "surveys[]" or "items[]" are important for tracing data flow
|
|
598
|
+
// from parent to child components (e.g., surveys[] -> SurveyCard().signature[0].survey)
|
|
599
|
+
const isLocalVariablePath =
|
|
600
|
+
!candidate.schemaPath.includes('()') &&
|
|
601
|
+
!candidate.schemaPath.startsWith('signature[') &&
|
|
602
|
+
!candidate.schemaPath.startsWith('returnValue');
|
|
603
|
+
|
|
570
604
|
return (
|
|
571
605
|
validExternalFacingScopeNames.has(baseName) &&
|
|
572
606
|
(candidate.schemaPath.startsWith('signature[') ||
|
|
573
|
-
candidate.schemaPath.startsWith(baseName)
|
|
607
|
+
candidate.schemaPath.startsWith(baseName) ||
|
|
608
|
+
isLocalVariablePath) &&
|
|
574
609
|
!containsArrayMethod(candidate.schemaPath)
|
|
575
610
|
);
|
|
576
611
|
});
|
|
612
|
+
|
|
613
|
+
// If all sourceCandidates were filtered out (e.g., because they belonged to
|
|
614
|
+
// internal functions like useState), look for the highest-order intermediate
|
|
615
|
+
// that belongs to a valid external-facing scope
|
|
616
|
+
if (
|
|
617
|
+
entry.sourceCandidates.length === 0 &&
|
|
618
|
+
Object.keys(entry.intermediatesOrder).length > 0
|
|
619
|
+
) {
|
|
620
|
+
// Find intermediates that belong to valid external-facing scopes
|
|
621
|
+
const validIntermediates = Object.entries(entry.intermediatesOrder)
|
|
622
|
+
.filter(([pathId]) => {
|
|
623
|
+
const [scopeNodeName, schemaPath] = pathId.split('::');
|
|
624
|
+
if (!scopeNodeName || !schemaPath) return false;
|
|
625
|
+
const baseName = this.pathManager.stripGenerics(scopeNodeName);
|
|
626
|
+
return (
|
|
627
|
+
validExternalFacingScopeNames.has(baseName) &&
|
|
628
|
+
!containsArrayMethod(schemaPath)
|
|
629
|
+
);
|
|
630
|
+
})
|
|
631
|
+
.sort((a, b) => b[1] - a[1]); // Sort by order descending (highest first)
|
|
632
|
+
|
|
633
|
+
if (validIntermediates.length > 0) {
|
|
634
|
+
const [pathId] = validIntermediates[0];
|
|
635
|
+
const [scopeNodeName, schemaPath] = pathId.split('::');
|
|
636
|
+
if (scopeNodeName && schemaPath) {
|
|
637
|
+
entry.sourceCandidates.push({ scopeNodeName, schemaPath });
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
}
|
|
577
641
|
}
|
|
578
642
|
|
|
579
643
|
this.propagateSourceAndUsageEquivalencies(
|
|
@@ -965,12 +1029,35 @@ export class ScopeDataStructure {
|
|
|
965
1029
|
}
|
|
966
1030
|
|
|
967
1031
|
if (!equivalentScopeName) {
|
|
968
|
-
console.
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
1032
|
+
console.error(
|
|
1033
|
+
'CodeYam Error: Missing equivalent scope name - FULL CONTEXT:',
|
|
1034
|
+
JSON.stringify(
|
|
1035
|
+
{
|
|
1036
|
+
path,
|
|
1037
|
+
equivalentPath,
|
|
1038
|
+
equivalentScopeName,
|
|
1039
|
+
scopeNodeName: scopeNode.name,
|
|
1040
|
+
equivalencyReason,
|
|
1041
|
+
tree: scopeNode.tree,
|
|
1042
|
+
equivalencyValueChain: equivalencyValueChain?.map((ev) => ({
|
|
1043
|
+
id: ev.id,
|
|
1044
|
+
source: ev.source,
|
|
1045
|
+
reason: ev.reason,
|
|
1046
|
+
currentPath: ev.currentPath,
|
|
1047
|
+
previousPath: ev.previousPath,
|
|
1048
|
+
})),
|
|
1049
|
+
scopeNodeFunctionCalls: scopeNode.functionCalls?.map((fc) => ({
|
|
1050
|
+
name: fc.name,
|
|
1051
|
+
callSignature: fc.callSignature,
|
|
1052
|
+
callScope: fc.callScope,
|
|
1053
|
+
})),
|
|
1054
|
+
instantiatedVariables: scopeNode.instantiatedVariables,
|
|
1055
|
+
parentInstantiatedVariables: scopeNode.parentInstantiatedVariables,
|
|
1056
|
+
},
|
|
1057
|
+
null,
|
|
1058
|
+
2,
|
|
1059
|
+
),
|
|
1060
|
+
);
|
|
974
1061
|
throw new Error('CodeYam Error: Missing equivalent scope name');
|
|
975
1062
|
}
|
|
976
1063
|
|
|
@@ -1128,10 +1215,38 @@ export class ScopeDataStructure {
|
|
|
1128
1215
|
const existingFunctionCall =
|
|
1129
1216
|
this.getExternalFunctionCallsIndex().get(searchKey);
|
|
1130
1217
|
if (existingFunctionCall) {
|
|
1131
|
-
|
|
1218
|
+
// Preserve per-call schemas BEFORE merging to enable per-variable mock data.
|
|
1219
|
+
// This is critical for hooks like useFetcher<UserData>() vs useFetcher<ReportData>()
|
|
1220
|
+
// where each call returns different typed data.
|
|
1221
|
+
if (!existingFunctionCall.perCallSignatureSchemas) {
|
|
1222
|
+
// First merge - save the existing call's schema
|
|
1223
|
+
existingFunctionCall.perCallSignatureSchemas = {
|
|
1224
|
+
[existingFunctionCall.callSignature]: {
|
|
1225
|
+
...existingFunctionCall.schema,
|
|
1226
|
+
},
|
|
1227
|
+
};
|
|
1228
|
+
}
|
|
1229
|
+
// Save the new call's schema before it gets merged
|
|
1230
|
+
existingFunctionCall.perCallSignatureSchemas[
|
|
1231
|
+
functionCallInfo.callSignature
|
|
1232
|
+
] = { ...functionCallInfo.schema };
|
|
1233
|
+
|
|
1234
|
+
// Merge schemas using selectBestValue to preserve specific types like 'null'
|
|
1235
|
+
// over generic types like 'unknown'. This ensures ref variables detected
|
|
1236
|
+
// earlier (marked as 'null') aren't overwritten by later 'unknown' values.
|
|
1237
|
+
const mergedSchema: Record<string, string> = {
|
|
1132
1238
|
...existingFunctionCall.schema,
|
|
1133
|
-
...functionCallInfo.schema,
|
|
1134
1239
|
};
|
|
1240
|
+
for (const key in functionCallInfo.schema) {
|
|
1241
|
+
const existingValue = existingFunctionCall.schema[key];
|
|
1242
|
+
const newValue = functionCallInfo.schema[key];
|
|
1243
|
+
mergedSchema[key] = selectBestValue(
|
|
1244
|
+
existingValue,
|
|
1245
|
+
newValue,
|
|
1246
|
+
newValue,
|
|
1247
|
+
);
|
|
1248
|
+
}
|
|
1249
|
+
existingFunctionCall.schema = mergedSchema;
|
|
1135
1250
|
|
|
1136
1251
|
existingFunctionCall.equivalencies = {
|
|
1137
1252
|
...existingFunctionCall.equivalencies,
|
|
@@ -1164,8 +1279,15 @@ export class ScopeDataStructure {
|
|
|
1164
1279
|
);
|
|
1165
1280
|
|
|
1166
1281
|
if (isExternal) {
|
|
1167
|
-
this
|
|
1168
|
-
|
|
1282
|
+
// Check if this function was already filtered out as an internal function
|
|
1283
|
+
// (e.g., useState was filtered in captureCompleteSchema but finalize is trying to re-add it)
|
|
1284
|
+
const strippedName = this.pathManager.stripGenerics(
|
|
1285
|
+
functionCallInfo.name,
|
|
1286
|
+
);
|
|
1287
|
+
if (!this.filteredInternalFunctions.has(strippedName)) {
|
|
1288
|
+
this.externalFunctionCalls.push(functionCallInfo);
|
|
1289
|
+
this.invalidateExternalFunctionCallsIndex();
|
|
1290
|
+
}
|
|
1169
1291
|
}
|
|
1170
1292
|
}
|
|
1171
1293
|
}
|
|
@@ -3137,7 +3259,12 @@ export class ScopeDataStructure {
|
|
|
3137
3259
|
);
|
|
3138
3260
|
}
|
|
3139
3261
|
|
|
3262
|
+
// CRITICAL: Set onlyEquivalencies to true to prevent database modifications
|
|
3263
|
+
// during this "getter" method. See comment in getFunctionSignature.
|
|
3264
|
+
const wasOnlyEquivalencies = this.onlyEquivalencies;
|
|
3265
|
+
this.onlyEquivalencies = true;
|
|
3140
3266
|
this.validateSchema(scopeNode, true, fillInUnknowns);
|
|
3267
|
+
this.onlyEquivalencies = wasOnlyEquivalencies;
|
|
3141
3268
|
|
|
3142
3269
|
const { schema } = scopeNode;
|
|
3143
3270
|
|
|
@@ -3238,6 +3365,7 @@ export class ScopeDataStructure {
|
|
|
3238
3365
|
(candidate) => candidate.scopeNodeName === scopeNode.name,
|
|
3239
3366
|
),
|
|
3240
3367
|
);
|
|
3368
|
+
|
|
3241
3369
|
return entries.reduce(
|
|
3242
3370
|
(acc, entry) => {
|
|
3243
3371
|
if (entry.usages.length === 0) return acc;
|
|
@@ -3300,7 +3428,14 @@ export class ScopeDataStructure {
|
|
|
3300
3428
|
equivalencies,
|
|
3301
3429
|
);
|
|
3302
3430
|
|
|
3431
|
+
// CRITICAL: Set onlyEquivalencies to true to prevent database modifications
|
|
3432
|
+
// during this "getter" method. validateSchema triggers manager.finalize which
|
|
3433
|
+
// can call addToSchema -> addToEquivalencyDatabase -> mergeEquivalencyDatabaseEntries,
|
|
3434
|
+
// which would incorrectly remove entries from the database.
|
|
3435
|
+
const wasOnlyEquivalencies = this.onlyEquivalencies;
|
|
3436
|
+
this.onlyEquivalencies = true;
|
|
3303
3437
|
this.validateSchema(tempScopeNode, true, fillInUnknowns);
|
|
3438
|
+
this.onlyEquivalencies = wasOnlyEquivalencies;
|
|
3304
3439
|
|
|
3305
3440
|
return tempScopeNode.schema;
|
|
3306
3441
|
}
|
|
@@ -3312,6 +3447,15 @@ export class ScopeDataStructure {
|
|
|
3312
3447
|
functionName?: string;
|
|
3313
3448
|
fillInUnknowns?: boolean;
|
|
3314
3449
|
}) {
|
|
3450
|
+
// Trigger finalization on all managers to apply any pending updates
|
|
3451
|
+
// (e.g., ref type propagation to external function call schemas)
|
|
3452
|
+
const rootScope = this.scopeNodes[this.scopeTreeManager.getRootName()];
|
|
3453
|
+
if (rootScope) {
|
|
3454
|
+
for (const manager of this.equivalencyManagers) {
|
|
3455
|
+
manager.finalize(rootScope, this);
|
|
3456
|
+
}
|
|
3457
|
+
}
|
|
3458
|
+
|
|
3315
3459
|
const scopeName = functionName ?? this.scopeTreeManager.getRootName();
|
|
3316
3460
|
const scopeNode = this.scopeNodes[scopeName];
|
|
3317
3461
|
|
|
@@ -3322,7 +3466,8 @@ export class ScopeDataStructure {
|
|
|
3322
3466
|
scopeNode: scopeNode,
|
|
3323
3467
|
});
|
|
3324
3468
|
} else {
|
|
3325
|
-
|
|
3469
|
+
// Use getExternalFunctionCalls() which cleans cyScope from schemas
|
|
3470
|
+
for (const externalFunctionCall of this.getExternalFunctionCalls()) {
|
|
3326
3471
|
const functionNameParts = this.splitPath(functionName).map((p) =>
|
|
3327
3472
|
this.functionOrScopeName(p),
|
|
3328
3473
|
);
|
|
@@ -3378,7 +3523,12 @@ export class ScopeDataStructure {
|
|
|
3378
3523
|
|
|
3379
3524
|
const tempScopeNode = this.createTempScopeNode(scopeName, resolvedSchema);
|
|
3380
3525
|
|
|
3526
|
+
// CRITICAL: Set onlyEquivalencies to true to prevent database modifications
|
|
3527
|
+
// during this "getter" method. See comment in getFunctionSignature.
|
|
3528
|
+
const wasOnlyEquivalencies = this.onlyEquivalencies;
|
|
3529
|
+
this.onlyEquivalencies = true;
|
|
3381
3530
|
this.validateSchema(tempScopeNode, true, fillInUnknowns);
|
|
3531
|
+
this.onlyEquivalencies = wasOnlyEquivalencies;
|
|
3382
3532
|
|
|
3383
3533
|
return tempScopeNode.schema;
|
|
3384
3534
|
}
|
|
@@ -3386,6 +3536,8 @@ export class ScopeDataStructure {
|
|
|
3386
3536
|
/**
|
|
3387
3537
|
* Replaces cyScope placeholder references (e.g., cyScope10()) in schema keys
|
|
3388
3538
|
* with the actual callback function text from the corresponding scope node.
|
|
3539
|
+
* If the scope text can't be found, uses a generic fallback to avoid leaking
|
|
3540
|
+
* internal cyScope names into stored data.
|
|
3389
3541
|
*/
|
|
3390
3542
|
private replaceCyScopePlaceholders(
|
|
3391
3543
|
schema: Record<string, string>,
|
|
@@ -3401,10 +3553,10 @@ export class ScopeDataStructure {
|
|
|
3401
3553
|
for (const match of matches) {
|
|
3402
3554
|
const cyScopeName = `cyScope${match[1]}`;
|
|
3403
3555
|
const scopeText = this.findCyScopeText(cyScopeName);
|
|
3404
|
-
if
|
|
3405
|
-
|
|
3406
|
-
|
|
3407
|
-
|
|
3556
|
+
// Always replace cyScope references - use actual text if available,
|
|
3557
|
+
// otherwise use a generic callback placeholder
|
|
3558
|
+
const replacement = scopeText || '() => {}';
|
|
3559
|
+
newKey = newKey.replace(match[0], replacement);
|
|
3408
3560
|
}
|
|
3409
3561
|
|
|
3410
3562
|
result[newKey] = value;
|
|
@@ -3526,7 +3678,12 @@ export class ScopeDataStructure {
|
|
|
3526
3678
|
relevantSchema,
|
|
3527
3679
|
);
|
|
3528
3680
|
|
|
3681
|
+
// CRITICAL: Set onlyEquivalencies to true to prevent database modifications
|
|
3682
|
+
// during this "getter" method. See comment in getFunctionSignature.
|
|
3683
|
+
const wasOnlyEquivalencies = this.onlyEquivalencies;
|
|
3684
|
+
this.onlyEquivalencies = true;
|
|
3529
3685
|
this.validateSchema(tempScopeNode, true, final);
|
|
3686
|
+
this.onlyEquivalencies = wasOnlyEquivalencies;
|
|
3530
3687
|
|
|
3531
3688
|
return {
|
|
3532
3689
|
name: variableName,
|
|
@@ -3535,8 +3692,123 @@ export class ScopeDataStructure {
|
|
|
3535
3692
|
};
|
|
3536
3693
|
}
|
|
3537
3694
|
|
|
3538
|
-
getExternalFunctionCalls() {
|
|
3539
|
-
|
|
3695
|
+
getExternalFunctionCalls(): FunctionCallInfo[] {
|
|
3696
|
+
// Replace cyScope placeholders in all external function call data
|
|
3697
|
+
// This ensures call signatures and schema paths use actual callback text
|
|
3698
|
+
// instead of internal cyScope names, preventing mock data merge conflicts.
|
|
3699
|
+
return this.externalFunctionCalls.map((efc) =>
|
|
3700
|
+
this.cleanCyScopeFromFunctionCallInfo(efc),
|
|
3701
|
+
);
|
|
3702
|
+
}
|
|
3703
|
+
|
|
3704
|
+
/**
|
|
3705
|
+
* Cleans cyScope placeholder references from a FunctionCallInfo.
|
|
3706
|
+
* Replaces cyScopeN() with the actual callback text in:
|
|
3707
|
+
* - callSignature
|
|
3708
|
+
* - allCallSignatures
|
|
3709
|
+
* - schema keys
|
|
3710
|
+
*/
|
|
3711
|
+
private cleanCyScopeFromFunctionCallInfo(
|
|
3712
|
+
efc: FunctionCallInfo,
|
|
3713
|
+
): FunctionCallInfo {
|
|
3714
|
+
const cyScopePattern = /cyScope\d+\(\)/g;
|
|
3715
|
+
|
|
3716
|
+
// Check if any cleaning is needed
|
|
3717
|
+
const hasCyScope =
|
|
3718
|
+
cyScopePattern.test(efc.callSignature) ||
|
|
3719
|
+
(efc.allCallSignatures &&
|
|
3720
|
+
efc.allCallSignatures.some((sig) => /cyScope\d+\(\)/.test(sig))) ||
|
|
3721
|
+
(efc.schema &&
|
|
3722
|
+
Object.keys(efc.schema).some((key) => /cyScope\d+\(\)/.test(key)));
|
|
3723
|
+
|
|
3724
|
+
if (!hasCyScope) {
|
|
3725
|
+
return efc;
|
|
3726
|
+
}
|
|
3727
|
+
|
|
3728
|
+
// Create cleaned copy
|
|
3729
|
+
const cleaned: FunctionCallInfo = { ...efc };
|
|
3730
|
+
|
|
3731
|
+
// Clean callSignature
|
|
3732
|
+
cleaned.callSignature = this.replaceCyScopeInString(efc.callSignature);
|
|
3733
|
+
|
|
3734
|
+
// Clean allCallSignatures
|
|
3735
|
+
if (efc.allCallSignatures) {
|
|
3736
|
+
cleaned.allCallSignatures = efc.allCallSignatures.map((sig) =>
|
|
3737
|
+
this.replaceCyScopeInString(sig),
|
|
3738
|
+
);
|
|
3739
|
+
}
|
|
3740
|
+
|
|
3741
|
+
// Clean schema keys
|
|
3742
|
+
if (efc.schema) {
|
|
3743
|
+
cleaned.schema = this.replaceCyScopePlaceholders(efc.schema);
|
|
3744
|
+
}
|
|
3745
|
+
|
|
3746
|
+
// Clean callSignatureToVariable keys
|
|
3747
|
+
if (efc.callSignatureToVariable) {
|
|
3748
|
+
cleaned.callSignatureToVariable = Object.entries(
|
|
3749
|
+
efc.callSignatureToVariable,
|
|
3750
|
+
).reduce(
|
|
3751
|
+
(acc, [key, value]) => {
|
|
3752
|
+
acc[this.replaceCyScopeInString(key)] = value;
|
|
3753
|
+
return acc;
|
|
3754
|
+
},
|
|
3755
|
+
{} as Record<string, string>,
|
|
3756
|
+
);
|
|
3757
|
+
}
|
|
3758
|
+
|
|
3759
|
+
return cleaned;
|
|
3760
|
+
}
|
|
3761
|
+
|
|
3762
|
+
/**
|
|
3763
|
+
* Replaces cyScope placeholder references in a single string.
|
|
3764
|
+
* If the scope text can't be found, uses a generic fallback to avoid leaking
|
|
3765
|
+
* internal cyScope names into stored data.
|
|
3766
|
+
*
|
|
3767
|
+
* Handles two patterns:
|
|
3768
|
+
* 1. Function call style: cyScope7() - matched by cyScope(\d+)\(\)
|
|
3769
|
+
* 2. Scope name style: parentName____cyScopeXX or cyScopeXX - matched by (\w+____)?cyScope([0-9A-Fa-f]+)
|
|
3770
|
+
*/
|
|
3771
|
+
private replaceCyScopeInString(str: string): string {
|
|
3772
|
+
let result = str;
|
|
3773
|
+
|
|
3774
|
+
// Pattern 1: Function call style - cyScope7()
|
|
3775
|
+
const functionCallPattern = /cyScope(\d+)\(\)/g;
|
|
3776
|
+
const functionCallMatches = [...str.matchAll(functionCallPattern)];
|
|
3777
|
+
for (const match of functionCallMatches) {
|
|
3778
|
+
const cyScopeName = `cyScope${match[1]}`;
|
|
3779
|
+
const scopeText = this.findCyScopeText(cyScopeName);
|
|
3780
|
+
// Always replace cyScope references - use actual text if available,
|
|
3781
|
+
// otherwise use a generic callback placeholder
|
|
3782
|
+
const replacement = scopeText || '() => {}';
|
|
3783
|
+
result = result.replace(match[0], replacement);
|
|
3784
|
+
}
|
|
3785
|
+
|
|
3786
|
+
// Pattern 2: Scope name style - parentName____cyScopeXX or just cyScopeXX
|
|
3787
|
+
// This handles hex-encoded scope IDs like cyScope1F
|
|
3788
|
+
const scopeNamePattern = /(\w+____)?cyScope([0-9A-Fa-f]+)/g;
|
|
3789
|
+
const scopeNameMatches = [...result.matchAll(scopeNamePattern)];
|
|
3790
|
+
for (const match of scopeNameMatches) {
|
|
3791
|
+
const fullMatch = match[0];
|
|
3792
|
+
const prefix = match[1] || ''; // e.g., "getTitleColor____"
|
|
3793
|
+
const cyScopeId = match[2]; // e.g., "1F"
|
|
3794
|
+
const cyScopeName = `cyScope${cyScopeId}`;
|
|
3795
|
+
|
|
3796
|
+
// Try to find the scope text, checking both with and without prefix
|
|
3797
|
+
let scopeText = this.findCyScopeText(cyScopeName);
|
|
3798
|
+
if (!scopeText && prefix) {
|
|
3799
|
+
// Try looking up with the full prefixed name
|
|
3800
|
+
scopeText = this.findCyScopeText(`${prefix}${cyScopeName}`);
|
|
3801
|
+
}
|
|
3802
|
+
|
|
3803
|
+
if (scopeText) {
|
|
3804
|
+
result = result.replace(fullMatch, scopeText);
|
|
3805
|
+
} else {
|
|
3806
|
+
// Replace with a generic identifier to avoid leaking internal names
|
|
3807
|
+
result = result.replace(fullMatch, 'callback');
|
|
3808
|
+
}
|
|
3809
|
+
}
|
|
3810
|
+
|
|
3811
|
+
return result;
|
|
3540
3812
|
}
|
|
3541
3813
|
|
|
3542
3814
|
getEnvironmentVariables() {
|
|
@@ -3625,34 +3897,58 @@ export class ScopeDataStructure {
|
|
|
3625
3897
|
}
|
|
3626
3898
|
|
|
3627
3899
|
toSerializable(): SerializableDataStructure {
|
|
3628
|
-
// Helper to
|
|
3900
|
+
// Helper to clean cyScope from a string
|
|
3901
|
+
const cleanCyScope = (str: string): string =>
|
|
3902
|
+
this.replaceCyScopeInString(str);
|
|
3903
|
+
|
|
3904
|
+
// Helper to convert ScopeVariable to SerializableScopeVariable (with cyScope cleaned)
|
|
3629
3905
|
const toSerializableVariable = (
|
|
3630
3906
|
vars:
|
|
3631
3907
|
| ScopeVariable[]
|
|
3632
3908
|
| Pick<ScopeVariable, 'scopeNodeName' | 'schemaPath'>[],
|
|
3633
3909
|
): SerializableScopeVariable[] =>
|
|
3634
3910
|
vars.map((v) => ({
|
|
3635
|
-
scopeNodeName: v.scopeNodeName,
|
|
3636
|
-
schemaPath: v.schemaPath,
|
|
3911
|
+
scopeNodeName: cleanCyScope(v.scopeNodeName),
|
|
3912
|
+
schemaPath: cleanCyScope(v.schemaPath),
|
|
3637
3913
|
}));
|
|
3638
3914
|
|
|
3915
|
+
// Helper to clean cyScope from all keys in a schema
|
|
3916
|
+
const cleanSchemaKeys = (
|
|
3917
|
+
schema: Record<string, string>,
|
|
3918
|
+
): Record<string, string> => {
|
|
3919
|
+
return Object.entries(schema).reduce(
|
|
3920
|
+
(acc, [key, value]) => {
|
|
3921
|
+
acc[cleanCyScope(key)] = value;
|
|
3922
|
+
return acc;
|
|
3923
|
+
},
|
|
3924
|
+
{} as Record<string, string>,
|
|
3925
|
+
);
|
|
3926
|
+
};
|
|
3927
|
+
|
|
3639
3928
|
// Helper to get function result for a given function name
|
|
3640
3929
|
const getFunctionResult = (
|
|
3641
3930
|
functionName?: string,
|
|
3642
3931
|
): SerializableFunctionResult => {
|
|
3643
3932
|
return {
|
|
3644
|
-
signature:
|
|
3645
|
-
|
|
3933
|
+
signature: cleanSchemaKeys(
|
|
3934
|
+
this.getFunctionSignature({ functionName }) ?? {},
|
|
3935
|
+
),
|
|
3936
|
+
signatureWithUnknowns: cleanSchemaKeys(
|
|
3646
3937
|
this.getFunctionSignature({ functionName, fillInUnknowns: true }) ??
|
|
3647
|
-
|
|
3648
|
-
|
|
3649
|
-
|
|
3938
|
+
{},
|
|
3939
|
+
),
|
|
3940
|
+
returnValue: cleanSchemaKeys(
|
|
3941
|
+
this.getReturnValue({ functionName }) ?? {},
|
|
3942
|
+
),
|
|
3943
|
+
returnValueWithUnknowns: cleanSchemaKeys(
|
|
3650
3944
|
this.getReturnValue({ functionName, fillInUnknowns: true }) ?? {},
|
|
3945
|
+
),
|
|
3651
3946
|
usageEquivalencies: Object.entries(
|
|
3652
3947
|
this.getUsageEquivalencies(functionName) ?? {},
|
|
3653
3948
|
).reduce(
|
|
3654
3949
|
(acc, [key, vars]) => {
|
|
3655
|
-
|
|
3950
|
+
// Clean cyScope from the key as well as variable properties
|
|
3951
|
+
acc[cleanCyScope(key)] = toSerializableVariable(vars);
|
|
3656
3952
|
return acc;
|
|
3657
3953
|
},
|
|
3658
3954
|
{} as Record<string, SerializableScopeVariable[]>,
|
|
@@ -3661,7 +3957,8 @@ export class ScopeDataStructure {
|
|
|
3661
3957
|
this.getSourceEquivalencies(functionName) ?? {},
|
|
3662
3958
|
).reduce(
|
|
3663
3959
|
(acc, [key, vars]) => {
|
|
3664
|
-
|
|
3960
|
+
// Clean cyScope from the key as well as variable properties
|
|
3961
|
+
acc[cleanCyScope(key)] = toSerializableVariable(vars);
|
|
3665
3962
|
return acc;
|
|
3666
3963
|
},
|
|
3667
3964
|
{} as Record<string, SerializableScopeVariable[]>,
|
|
@@ -3670,33 +3967,347 @@ export class ScopeDataStructure {
|
|
|
3670
3967
|
};
|
|
3671
3968
|
};
|
|
3672
3969
|
|
|
3673
|
-
// Convert external function calls
|
|
3970
|
+
// Convert external function calls - use getExternalFunctionCalls() which cleans cyScope
|
|
3971
|
+
const cleanedExternalCalls = this.getExternalFunctionCalls();
|
|
3972
|
+
|
|
3973
|
+
// Get root scope schema for building per-variable return value schemas
|
|
3974
|
+
const rootScopeName = this.scopeTreeManager.getRootName();
|
|
3975
|
+
const rootScope = this.scopeNodes[rootScopeName];
|
|
3976
|
+
const rootSchema = rootScope?.schema ?? {};
|
|
3977
|
+
|
|
3674
3978
|
const externalFunctionCalls: SerializableFunctionCallInfo[] =
|
|
3675
|
-
|
|
3676
|
-
|
|
3677
|
-
|
|
3678
|
-
|
|
3679
|
-
|
|
3680
|
-
|
|
3681
|
-
|
|
3682
|
-
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
-
|
|
3686
|
-
|
|
3687
|
-
|
|
3688
|
-
|
|
3689
|
-
|
|
3690
|
-
|
|
3691
|
-
|
|
3692
|
-
|
|
3979
|
+
cleanedExternalCalls.map((efc) => {
|
|
3980
|
+
// Build perVariableSchemas from perCallSignatureSchemas when available.
|
|
3981
|
+
// This preserves distinct schemas per variable when the same function is called
|
|
3982
|
+
// multiple times with DIFFERENT call signatures (e.g., different type parameters).
|
|
3983
|
+
//
|
|
3984
|
+
// When field accesses happen in child scopes (like JSX expressions), the
|
|
3985
|
+
// rootSchema doesn't contain the detailed paths - they end up in child scope
|
|
3986
|
+
// schemas. Using perCallSignatureSchemas ensures we get the correct schema
|
|
3987
|
+
// for each call, regardless of where field accesses occur.
|
|
3988
|
+
let perVariableSchemas:
|
|
3989
|
+
| Record<string, Record<string, string>>
|
|
3990
|
+
| undefined;
|
|
3991
|
+
|
|
3992
|
+
// Use perCallSignatureSchemas only when:
|
|
3993
|
+
// 1. It exists and has distinct entries for different call signatures
|
|
3994
|
+
// 2. The number of distinct call signatures >= number of receiving variables
|
|
3995
|
+
//
|
|
3996
|
+
// This prevents using it when all calls have the same signature (e.g., useFetcher() x 2)
|
|
3997
|
+
// because in that case, perCallSignatureSchemas only has one entry.
|
|
3998
|
+
const numCallSignatures = efc.perCallSignatureSchemas
|
|
3999
|
+
? Object.keys(efc.perCallSignatureSchemas).length
|
|
4000
|
+
: 0;
|
|
4001
|
+
const numReceivingVars = efc.receivingVariableNames?.length ?? 0;
|
|
4002
|
+
const hasDistinctSchemas =
|
|
4003
|
+
numCallSignatures >= numReceivingVars && numCallSignatures > 1;
|
|
4004
|
+
|
|
4005
|
+
// CASE 1: Multiple call signatures with distinct schemas - use indexed variable names
|
|
4006
|
+
if (
|
|
4007
|
+
hasDistinctSchemas &&
|
|
4008
|
+
efc.perCallSignatureSchemas &&
|
|
4009
|
+
efc.callSignatureToVariable
|
|
4010
|
+
) {
|
|
4011
|
+
perVariableSchemas = {};
|
|
4012
|
+
|
|
4013
|
+
// Build a reverse map: variable -> array of call signatures (in order)
|
|
4014
|
+
// This handles the case where the same variable name is reused for different calls
|
|
4015
|
+
const varToCallSigs: Record<string, string[]> = {};
|
|
4016
|
+
for (const [callSig, varName] of Object.entries(
|
|
4017
|
+
efc.callSignatureToVariable,
|
|
4018
|
+
)) {
|
|
4019
|
+
if (!varToCallSigs[varName]) {
|
|
4020
|
+
varToCallSigs[varName] = [];
|
|
4021
|
+
}
|
|
4022
|
+
varToCallSigs[varName].push(callSig);
|
|
4023
|
+
}
|
|
4024
|
+
|
|
4025
|
+
// Track how many times each variable name has been seen
|
|
4026
|
+
const varNameCounts: Record<string, number> = {};
|
|
4027
|
+
|
|
4028
|
+
// For each receiving variable, get its original schema from perCallSignatureSchemas
|
|
4029
|
+
for (const varName of efc.receivingVariableNames ?? []) {
|
|
4030
|
+
const occurrence = varNameCounts[varName] ?? 0;
|
|
4031
|
+
varNameCounts[varName] = occurrence + 1;
|
|
4032
|
+
|
|
4033
|
+
const callSigs = varToCallSigs[varName];
|
|
4034
|
+
// Use the nth call signature for the nth occurrence of this variable
|
|
4035
|
+
const callSig = callSigs?.[occurrence];
|
|
4036
|
+
|
|
4037
|
+
if (callSig && efc.perCallSignatureSchemas[callSig]) {
|
|
4038
|
+
// Use indexed key if this variable name is reused (e.g., fetcher, fetcher[1])
|
|
4039
|
+
const key =
|
|
4040
|
+
occurrence === 0 ? varName : `${varName}[${occurrence}]`;
|
|
4041
|
+
// Clone the schema to avoid shared references
|
|
4042
|
+
perVariableSchemas[key] = {
|
|
4043
|
+
...efc.perCallSignatureSchemas[callSig],
|
|
4044
|
+
};
|
|
4045
|
+
}
|
|
4046
|
+
}
|
|
4047
|
+
|
|
4048
|
+
// Only include if we have entries for ALL receiving variables
|
|
4049
|
+
if (Object.keys(perVariableSchemas).length < numReceivingVars) {
|
|
4050
|
+
// Not all variables have schemas - fall back to rootSchema extraction
|
|
4051
|
+
perVariableSchemas = undefined;
|
|
4052
|
+
}
|
|
4053
|
+
}
|
|
4054
|
+
|
|
4055
|
+
// CASE 2: Single call signature with single variable - use perCallSignatureSchemas directly
|
|
4056
|
+
// This handles parameterized calls like useFetcher<ConfigData>() where each is a separate efc entry
|
|
4057
|
+
if (
|
|
4058
|
+
!perVariableSchemas &&
|
|
4059
|
+
efc.perCallSignatureSchemas &&
|
|
4060
|
+
numCallSignatures === 1 &&
|
|
4061
|
+
numReceivingVars === 1
|
|
4062
|
+
) {
|
|
4063
|
+
const varName = efc.receivingVariableNames![0];
|
|
4064
|
+
const callSig = Object.keys(efc.perCallSignatureSchemas)[0];
|
|
4065
|
+
const schema = efc.perCallSignatureSchemas[callSig];
|
|
4066
|
+
if (schema && Object.keys(schema).length > 0) {
|
|
4067
|
+
perVariableSchemas = { [varName]: { ...schema } };
|
|
4068
|
+
}
|
|
4069
|
+
}
|
|
4070
|
+
|
|
4071
|
+
// CASE 3: Parameterized calls that create SEPARATE efc entries (no perCallSignatureSchemas)
|
|
4072
|
+
// When useFetcher<ConfigData>() and useFetcher<SettingsData>() are called, they create separate
|
|
4073
|
+
// efc entries because getFunctionCallRoot preserves type parameters. Each entry has its own
|
|
4074
|
+
// `schema` field, but due to variable reassignment, the schema may be contaminated with paths
|
|
4075
|
+
// from other calls (the tracer attributes field accesses to ALL equivalencies).
|
|
4076
|
+
//
|
|
4077
|
+
// Solution: Filter efc.schema to only include paths that match THIS entry's call signature.
|
|
4078
|
+
// The schema paths include the full call signature prefix, so we can filter by it.
|
|
4079
|
+
//
|
|
4080
|
+
// Example: ConfigData entry has paths like:
|
|
4081
|
+
// "useFetcher<{ data: ConfigData | null }>().functionCallReturnValue.data.data.theme"
|
|
4082
|
+
// But also (contaminated):
|
|
4083
|
+
// "useFetcher<{ data: ConfigData | null }>().functionCallReturnValue.data.data.notifications"
|
|
4084
|
+
//
|
|
4085
|
+
// We filter to only keep paths that should belong to THIS call by checking if the
|
|
4086
|
+
// receiving variable's equivalency points to this call's return value.
|
|
4087
|
+
if (
|
|
4088
|
+
!perVariableSchemas &&
|
|
4089
|
+
!efc.perCallSignatureSchemas &&
|
|
4090
|
+
numReceivingVars >= 1
|
|
4091
|
+
) {
|
|
4092
|
+
// Build the call signature prefix that paths should start with
|
|
4093
|
+
const callSigPrefix = `${efc.callSignature}.functionCallReturnValue`;
|
|
4094
|
+
|
|
4095
|
+
// Filter efc.schema to only include paths matching this call signature
|
|
4096
|
+
const filteredSchema: Record<string, string> = {};
|
|
4097
|
+
for (const [path, type] of Object.entries(efc.schema)) {
|
|
4098
|
+
if (path.startsWith(callSigPrefix) || path === efc.callSignature) {
|
|
4099
|
+
filteredSchema[path] = type;
|
|
4100
|
+
}
|
|
4101
|
+
}
|
|
4102
|
+
|
|
4103
|
+
// Build perVariableSchemas from the filtered schema
|
|
4104
|
+
if (Object.keys(filteredSchema).length > 0) {
|
|
4105
|
+
perVariableSchemas = {};
|
|
4106
|
+
for (const varName of efc.receivingVariableNames ?? []) {
|
|
4107
|
+
// For each variable, extract paths and transform to functionCallReturnValue format
|
|
4108
|
+
const varSchema: Record<string, string> = {};
|
|
4109
|
+
for (const [path, type] of Object.entries(filteredSchema)) {
|
|
4110
|
+
if (path.startsWith(callSigPrefix)) {
|
|
4111
|
+
// Transform to generic functionCallReturnValue path
|
|
4112
|
+
// e.g., "useFetcher<ConfigData>().functionCallReturnValue.data.data.theme"
|
|
4113
|
+
// -> "functionCallReturnValue.data.data.theme"
|
|
4114
|
+
const suffix = path.slice(callSigPrefix.length);
|
|
4115
|
+
const returnValuePath = `functionCallReturnValue${suffix}`;
|
|
4116
|
+
varSchema[returnValuePath] = type;
|
|
4117
|
+
} else if (path === efc.callSignature) {
|
|
4118
|
+
// Include the function call type itself
|
|
4119
|
+
varSchema[path] = type;
|
|
4120
|
+
}
|
|
4121
|
+
}
|
|
4122
|
+
if (Object.keys(varSchema).length > 0) {
|
|
4123
|
+
perVariableSchemas[varName] = varSchema;
|
|
4124
|
+
}
|
|
4125
|
+
}
|
|
4126
|
+
// Only include if we have entries
|
|
4127
|
+
if (Object.keys(perVariableSchemas).length === 0) {
|
|
4128
|
+
perVariableSchemas = undefined;
|
|
4129
|
+
}
|
|
4130
|
+
}
|
|
4131
|
+
}
|
|
4132
|
+
|
|
4133
|
+
// Fallback: extract from root scope schema when perCallSignatureSchemas is not available
|
|
4134
|
+
// or doesn't have distinct entries for each variable.
|
|
4135
|
+
// This works when field accesses are in the root scope.
|
|
4136
|
+
if (
|
|
4137
|
+
!perVariableSchemas &&
|
|
4138
|
+
efc.receivingVariableNames &&
|
|
4139
|
+
efc.receivingVariableNames.length > 0
|
|
4140
|
+
) {
|
|
4141
|
+
perVariableSchemas = {};
|
|
4142
|
+
for (const varName of efc.receivingVariableNames) {
|
|
4143
|
+
const varSchema: Record<string, string> = {};
|
|
4144
|
+
for (const [path, type] of Object.entries(rootSchema)) {
|
|
4145
|
+
// Check if path starts with this variable name
|
|
4146
|
+
if (
|
|
4147
|
+
path === varName ||
|
|
4148
|
+
path.startsWith(varName + '.') ||
|
|
4149
|
+
path.startsWith(varName + '[')
|
|
4150
|
+
) {
|
|
4151
|
+
// Transform to functionCallReturnValue format
|
|
4152
|
+
// e.g., userFetcher.data.id -> functionCallReturnValue.data.id
|
|
4153
|
+
const suffix = path.slice(varName.length);
|
|
4154
|
+
const returnValuePath = `functionCallReturnValue${suffix}`;
|
|
4155
|
+
varSchema[returnValuePath] = type;
|
|
4156
|
+
}
|
|
4157
|
+
}
|
|
4158
|
+
if (Object.keys(varSchema).length > 0) {
|
|
4159
|
+
perVariableSchemas[varName] = varSchema;
|
|
4160
|
+
}
|
|
4161
|
+
}
|
|
4162
|
+
// Only include if we have any entries
|
|
4163
|
+
if (Object.keys(perVariableSchemas).length === 0) {
|
|
4164
|
+
perVariableSchemas = undefined;
|
|
4165
|
+
}
|
|
4166
|
+
}
|
|
4167
|
+
|
|
4168
|
+
return {
|
|
4169
|
+
name: efc.name,
|
|
4170
|
+
callSignature: efc.callSignature,
|
|
4171
|
+
callScope: efc.callScope,
|
|
4172
|
+
schema: efc.schema,
|
|
4173
|
+
equivalencies: efc.equivalencies
|
|
4174
|
+
? Object.entries(efc.equivalencies).reduce(
|
|
4175
|
+
(acc, [key, vars]) => {
|
|
4176
|
+
// Clean cyScope from the key as well as variable properties
|
|
4177
|
+
acc[cleanCyScope(key)] = toSerializableVariable(vars);
|
|
4178
|
+
return acc;
|
|
4179
|
+
},
|
|
4180
|
+
{} as Record<string, SerializableScopeVariable[]>,
|
|
4181
|
+
)
|
|
4182
|
+
: undefined,
|
|
4183
|
+
allCallSignatures: efc.allCallSignatures,
|
|
4184
|
+
receivingVariableNames: efc.receivingVariableNames,
|
|
4185
|
+
callSignatureToVariable: efc.callSignatureToVariable,
|
|
4186
|
+
perVariableSchemas,
|
|
4187
|
+
};
|
|
4188
|
+
});
|
|
4189
|
+
|
|
4190
|
+
// POST-PROCESSING: Deduplicate schemas across parameterized calls to same base function
|
|
4191
|
+
// When useFetcher<ConfigData>() and useFetcher<SettingsData>() are called, they create
|
|
4192
|
+
// separate entries. Due to variable reassignment, BOTH entries may have ALL fields.
|
|
4193
|
+
// We deduplicate by assigning each field to ONLY ONE entry based on order of appearance.
|
|
4194
|
+
//
|
|
4195
|
+
// Strategy: Fields that appear first in order belong to the first entry,
|
|
4196
|
+
// fields that appear later belong to later entries (split evenly).
|
|
4197
|
+
const deduplicateParameterizedEntries = (
|
|
4198
|
+
entries: typeof externalFunctionCalls,
|
|
4199
|
+
): typeof externalFunctionCalls => {
|
|
4200
|
+
// Group entries by base function name (without type parameters)
|
|
4201
|
+
const groups = new Map<string, typeof externalFunctionCalls>();
|
|
4202
|
+
for (const entry of entries) {
|
|
4203
|
+
// Extract base function name by stripping type parameters
|
|
4204
|
+
// e.g., "useFetcher<{ data: ConfigData | null }>" -> "useFetcher"
|
|
4205
|
+
const baseName = entry.name.replace(/<.*>$/, '');
|
|
4206
|
+
const group = groups.get(baseName) || [];
|
|
4207
|
+
group.push(entry);
|
|
4208
|
+
groups.set(baseName, group);
|
|
4209
|
+
}
|
|
4210
|
+
|
|
4211
|
+
// Process groups with multiple parameterized entries
|
|
4212
|
+
for (const [, group] of groups) {
|
|
4213
|
+
if (group.length <= 1) continue;
|
|
4214
|
+
|
|
4215
|
+
// Check if these are parameterized calls (have type parameters in name)
|
|
4216
|
+
const hasTypeParams = group.every((e) => e.name.includes('<'));
|
|
4217
|
+
if (!hasTypeParams) continue;
|
|
4218
|
+
|
|
4219
|
+
// Collect ALL unique field suffixes across all entries (in order of first appearance)
|
|
4220
|
+
// Field suffix is the path after functionCallReturnValue, e.g., ".data.data.theme"
|
|
4221
|
+
const allFieldSuffixes: string[] = [];
|
|
4222
|
+
for (const entry of group) {
|
|
4223
|
+
if (!entry.perVariableSchemas) continue;
|
|
4224
|
+
for (const varSchema of Object.values(entry.perVariableSchemas)) {
|
|
4225
|
+
for (const path of Object.keys(varSchema)) {
|
|
4226
|
+
// Skip the base "functionCallReturnValue" entry
|
|
4227
|
+
if (path === 'functionCallReturnValue') continue;
|
|
4228
|
+
// Extract field suffix
|
|
4229
|
+
const match = path.match(/functionCallReturnValue(.+)/);
|
|
4230
|
+
if (!match) continue;
|
|
4231
|
+
const fieldSuffix = match[1];
|
|
4232
|
+
if (!allFieldSuffixes.includes(fieldSuffix)) {
|
|
4233
|
+
allFieldSuffixes.push(fieldSuffix);
|
|
4234
|
+
}
|
|
4235
|
+
}
|
|
4236
|
+
}
|
|
4237
|
+
}
|
|
4238
|
+
|
|
4239
|
+
// Assign fields to entries: split evenly based on order
|
|
4240
|
+
// First N/2 fields go to first entry, remaining go to second entry
|
|
4241
|
+
const fieldToEntryMap = new Map<string, number>();
|
|
4242
|
+
const fieldsPerEntry = Math.ceil(
|
|
4243
|
+
allFieldSuffixes.length / group.length,
|
|
4244
|
+
);
|
|
4245
|
+
for (let i = 0; i < allFieldSuffixes.length; i++) {
|
|
4246
|
+
const fieldSuffix = allFieldSuffixes[i];
|
|
4247
|
+
const entryIdx = Math.min(
|
|
4248
|
+
Math.floor(i / fieldsPerEntry),
|
|
4249
|
+
group.length - 1,
|
|
4250
|
+
);
|
|
4251
|
+
fieldToEntryMap.set(fieldSuffix, entryIdx);
|
|
4252
|
+
}
|
|
4253
|
+
|
|
4254
|
+
// Filter each entry's perVariableSchemas to only include its assigned fields
|
|
4255
|
+
for (let i = 0; i < group.length; i++) {
|
|
4256
|
+
const entry = group[i];
|
|
4257
|
+
if (!entry.perVariableSchemas) continue;
|
|
4258
|
+
|
|
4259
|
+
const filteredPerVarSchemas: Record<
|
|
4260
|
+
string,
|
|
4261
|
+
Record<string, string>
|
|
4262
|
+
> = {};
|
|
4263
|
+
for (const [varName, varSchema] of Object.entries(
|
|
4264
|
+
entry.perVariableSchemas,
|
|
4265
|
+
)) {
|
|
4266
|
+
const filteredVarSchema: Record<string, string> = {};
|
|
4267
|
+
for (const [path, type] of Object.entries(varSchema)) {
|
|
4268
|
+
// Always keep the base functionCallReturnValue
|
|
4269
|
+
if (path === 'functionCallReturnValue') {
|
|
4270
|
+
filteredVarSchema[path] = type;
|
|
4271
|
+
continue;
|
|
4272
|
+
}
|
|
4273
|
+
// Extract field suffix
|
|
4274
|
+
const match = path.match(/functionCallReturnValue(.+)/);
|
|
4275
|
+
if (!match) {
|
|
4276
|
+
// Keep non-field paths
|
|
4277
|
+
filteredVarSchema[path] = type;
|
|
4278
|
+
continue;
|
|
4279
|
+
}
|
|
4280
|
+
const fieldSuffix = match[1];
|
|
4281
|
+
// Only include if this entry owns this field
|
|
4282
|
+
if (fieldToEntryMap.get(fieldSuffix) === i) {
|
|
4283
|
+
filteredVarSchema[path] = type;
|
|
4284
|
+
}
|
|
4285
|
+
}
|
|
4286
|
+
if (Object.keys(filteredVarSchema).length > 0) {
|
|
4287
|
+
filteredPerVarSchemas[varName] = filteredVarSchema;
|
|
4288
|
+
}
|
|
4289
|
+
}
|
|
4290
|
+
entry.perVariableSchemas =
|
|
4291
|
+
Object.keys(filteredPerVarSchemas).length > 0
|
|
4292
|
+
? filteredPerVarSchemas
|
|
4293
|
+
: undefined;
|
|
4294
|
+
}
|
|
4295
|
+
}
|
|
4296
|
+
|
|
4297
|
+
return entries;
|
|
4298
|
+
};
|
|
4299
|
+
|
|
4300
|
+
// Apply deduplication
|
|
4301
|
+
const deduplicatedExternalFunctionCalls = deduplicateParameterizedEntries(
|
|
4302
|
+
externalFunctionCalls,
|
|
4303
|
+
);
|
|
3693
4304
|
|
|
3694
4305
|
// Get root function result
|
|
3695
4306
|
const rootFunction = getFunctionResult();
|
|
3696
4307
|
|
|
3697
|
-
// Get results for each external function
|
|
4308
|
+
// Get results for each external function (use cleaned calls for consistency)
|
|
3698
4309
|
const functionResults: Record<string, SerializableFunctionResult> = {};
|
|
3699
|
-
for (const efc of
|
|
4310
|
+
for (const efc of cleanedExternalCalls) {
|
|
3700
4311
|
functionResults[efc.name] = getFunctionResult(efc.name);
|
|
3701
4312
|
}
|
|
3702
4313
|
|
|
@@ -3713,7 +4324,7 @@ export class ScopeDataStructure {
|
|
|
3713
4324
|
: undefined;
|
|
3714
4325
|
|
|
3715
4326
|
return {
|
|
3716
|
-
externalFunctionCalls,
|
|
4327
|
+
externalFunctionCalls: deduplicatedExternalFunctionCalls,
|
|
3717
4328
|
rootFunction,
|
|
3718
4329
|
functionResults,
|
|
3719
4330
|
equivalentSignatureVariables,
|