@codeyam/codeyam-cli 0.1.0-staging.596f0eb → 0.1.0-staging.76566f9
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 +2 -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 +734 -45
- package/analyzer-template/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/JavascriptFrameworkManager.ts +2 -1
- 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 +233 -75
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.ts +19 -1
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/cleanNonObjectFunctions.ts +34 -1
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/convertDotNotation.ts +23 -0
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/convertNullToUndefinedBySchema.ts +98 -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/generateChangesEntityScenarioData.ts +41 -0
- 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 +36 -25
- 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 +127 -43
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/enrichArrayTypesFromChildSignatures.ts +158 -0
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.ts +405 -45
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateChangesScenarioData.ts +1 -1
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateDataStructure.ts +260 -133
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateKeyAttributes.ts +10 -5
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateScenarioData.ts +77 -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 +196 -86
- 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/generate/src/lib/componentScenarioPage/getIFrameMessageListenerCode.ts +9 -4
- package/analyzer-template/packages/generate/src/lib/deepMerge.ts +26 -1
- 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/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/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/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/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/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/lightweightEntityExtractor.ts +27 -0
- package/analyzer-template/playwright/takeElementScreenshot.ts +26 -11
- package/analyzer-template/playwright/takeScreenshot.ts +9 -7
- package/analyzer-template/project/constructMockCode.ts +286 -84
- package/analyzer-template/project/orchestrateCapture/SequentialCaptureTaskRunner.ts +77 -37
- package/analyzer-template/project/reconcileMockDataKeys.ts +5 -2
- package/analyzer-template/project/runMultiScenarioServer.ts +11 -10
- package/analyzer-template/project/serverOnlyModules.ts +71 -23
- package/analyzer-template/project/start.ts +10 -0
- package/analyzer-template/project/startScenarioCapture.ts +73 -41
- package/analyzer-template/project/writeMockDataTsx.ts +115 -54
- package/analyzer-template/project/writeScenarioComponents.ts +571 -162
- package/analyzer-template/project/writeSimpleRoot.ts +11 -13
- package/background/src/lib/virtualized/project/constructMockCode.js +265 -75
- package/background/src/lib/virtualized/project/constructMockCode.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 +5 -2
- 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 +62 -25
- package/background/src/lib/virtualized/project/serverOnlyModules.js.map +1 -1
- 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 +106 -46
- package/background/src/lib/virtualized/project/writeMockDataTsx.js.map +1 -1
- package/background/src/lib/virtualized/project/writeScenarioComponents.js +399 -106
- package/background/src/lib/virtualized/project/writeScenarioComponents.js.map +1 -1
- package/background/src/lib/virtualized/project/writeSimpleRoot.js +11 -11
- package/background/src/lib/virtualized/project/writeSimpleRoot.js.map +1 -1
- 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 -2
- 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-efWKDYMr.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-COPstp9J.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)-CVP_WGQ3.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._-Dt-SjPsw.js +23 -0
- 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-C9s7Lhdl.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-0d27da29.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-B_wIKCIf.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-3pmpUQB-.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-DEyawJ8r.js → useToast-DWHcCcl1.js} +1 -1
- package/codeyam-cli/src/webserver/build/server/assets/index-CU58-Ttc.js +1 -0
- package/codeyam-cli/src/webserver/build/server/assets/server-build-D35o2uae.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/codeyam-setup-skill.md +138 -3
- package/codeyam-cli/templates/debug-codeyam.md +625 -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 +582 -41
- package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/JavascriptFrameworkManager.js +2 -1
- 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 +173 -55
- 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 +30 -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/convertNullToUndefinedBySchema.js +86 -0
- package/packages/ai/src/lib/dataStructure/helpers/convertNullToUndefinedBySchema.js.map +1 -0
- 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/generateChangesEntityScenarioData.js +41 -0
- package/packages/ai/src/lib/generateChangesEntityScenarioData.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 +29 -25
- 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 +100 -23
- package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.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 +298 -45
- 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 +201 -80
- 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 +55 -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 +171 -81
- 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/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/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/lightweightEntityExtractor.js +25 -0
- package/packages/utils/src/lib/lightweightEntityExtractor.js.map +1 -1
- package/scripts/finalize-analyzer.cjs +3 -1
- package/codeyam-cli/scripts/fixtures/cal.com/universal-mocks/packages/prisma/index.js +0 -238
- package/codeyam-cli/scripts/fixtures/cal.com/universal-mocks/packages/prisma/index.js.map +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/EntityItem-CVbSvOjo.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/EntityTypeIcon-DcwcHyl5.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/InteractivePreview-WgwC1GfJ.js +0 -26
- package/codeyam-cli/src/webserver/build/client/assets/LibraryFunctionPreview-IEKom9O2.js +0 -3
- package/codeyam-cli/src/webserver/build/client/assets/LogViewer-BYnfxbUG.js +0 -3
- package/codeyam-cli/src/webserver/build/client/assets/ReportIssueModal-_lBPJCzG.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/SafeScreenshot-lHVhvsu_.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/ScenarioViewer-d_TBk4GQ.js +0 -5
- package/codeyam-cli/src/webserver/build/client/assets/_index-kGT7VUqj.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/activity.(_tab)-DDGmhu7P.js +0 -7
- package/codeyam-cli/src/webserver/build/client/assets/chevron-down-n_HPRfM_.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/chunk-WWGJGFF6-CbVoyx1U.js +0 -26
- package/codeyam-cli/src/webserver/build/client/assets/circle-check-D1VOYveA.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/createLucideIcon-YR8jjAlu.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/dev.empty-B8vP3V_s.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha._-CN6aLCT1.js +0 -16
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.create-scenario-DA5Jeu2P.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.edit._scenarioId-BTeitalf.js +0 -5
- package/codeyam-cli/src/webserver/build/client/assets/entry.client-du6UEYD-.js +0 -13
- package/codeyam-cli/src/webserver/build/client/assets/fileTableUtils-BpjkhMoi.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/files-BQGvk4lJ.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/git-DVdYRT-I.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-DCG-vks0.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/loader-circle-GazdNeLl.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/manifest-0b694d28.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/root-D3tQP7hx.js +0 -16
- package/codeyam-cli/src/webserver/build/client/assets/search-CIY6XmtE.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-CoMDgElu.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/simulations-agkniXp2.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/triangle-alert-B2VUcygF.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/useReportContext-EvdK-zXP.js +0 -1
- package/codeyam-cli/src/webserver/build/server/assets/index-DGVHQEXD.js +0 -1
- package/codeyam-cli/src/webserver/build/server/assets/server-build-CghkTkIL.js +0 -166
- package/codeyam-cli/templates/debug-command.md +0 -303
- /package/codeyam-cli/src/webserver/build/client/assets/{InteractivePreview-CMKNK2uU.css → styles-CMKNK2uU.css} +0 -0
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import ts from 'typescript';
|
|
2
|
-
import
|
|
2
|
+
import * as crypto from 'crypto';
|
|
3
|
+
import {
|
|
4
|
+
AnalysisContext,
|
|
5
|
+
CompoundConditional,
|
|
6
|
+
ConditionalUsage,
|
|
7
|
+
} from './types';
|
|
3
8
|
import { StructuredPath } from './paths';
|
|
4
9
|
import { nodeToSource } from './nodeToSource';
|
|
5
10
|
import { methodRegistry, ArrayPushSemantics } from './methodSemantics';
|
|
@@ -15,6 +20,82 @@ import {
|
|
|
15
20
|
} from './sharedPatterns';
|
|
16
21
|
import { processBindingPattern } from './processBindings';
|
|
17
22
|
|
|
23
|
+
/**
|
|
24
|
+
* Converts a call expression argument to a StructuredPath.
|
|
25
|
+
*
|
|
26
|
+
* IMPORTANT: We always use the original source text for callbacks, never cyScope names.
|
|
27
|
+
* cyScope names are internal identifiers for child scopes and should NEVER appear
|
|
28
|
+
* in schema paths or call signatures. Using cyScope names causes data merge conflicts
|
|
29
|
+
* because the same callback gets different identifiers in different contexts.
|
|
30
|
+
*/
|
|
31
|
+
function getArgPathForCallSignature(
|
|
32
|
+
arg: ts.Expression,
|
|
33
|
+
context: AnalysisContext,
|
|
34
|
+
): StructuredPath {
|
|
35
|
+
// Always use the standard path conversion - never replace with cyScope names
|
|
36
|
+
return (
|
|
37
|
+
StructuredPath.fromNode(arg, context.sourceFile) ||
|
|
38
|
+
nodeToSource(arg, context.sourceFile)
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Builds a StructuredPath for a call expression using the original source text.
|
|
44
|
+
*
|
|
45
|
+
* IMPORTANT: This function ensures consistent call signatures by always using
|
|
46
|
+
* the original callback text, never cyScope names. This prevents schema path
|
|
47
|
+
* conflicts where the same call would have different paths.
|
|
48
|
+
*/
|
|
49
|
+
function buildCallPathFromSource(
|
|
50
|
+
node: ts.CallExpression,
|
|
51
|
+
context: AnalysisContext,
|
|
52
|
+
): StructuredPath | null {
|
|
53
|
+
const expression = node.expression;
|
|
54
|
+
|
|
55
|
+
// Convert arguments using original source text
|
|
56
|
+
const argPaths = node.arguments.map((arg) =>
|
|
57
|
+
getArgPathForCallSignature(arg, context),
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
// Handle type arguments if present
|
|
61
|
+
let typeArgs: string[] | undefined = undefined;
|
|
62
|
+
if (node.typeArguments && node.typeArguments.length > 0) {
|
|
63
|
+
typeArgs = node.typeArguments.map((typeArg) =>
|
|
64
|
+
typeArg.getText(context.sourceFile),
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (ts.isIdentifier(expression)) {
|
|
69
|
+
// Simple function call: func(arg1, arg2)
|
|
70
|
+
return StructuredPath.fromFunction(expression.text, argPaths, typeArgs);
|
|
71
|
+
} else if (ts.isPropertyAccessExpression(expression)) {
|
|
72
|
+
// Method call: obj.method(arg1, arg2)
|
|
73
|
+
const objPath = StructuredPath.fromNode(
|
|
74
|
+
expression.expression,
|
|
75
|
+
context.sourceFile,
|
|
76
|
+
);
|
|
77
|
+
if (!objPath) return null;
|
|
78
|
+
return objPath
|
|
79
|
+
.withProperty(expression.name.text)
|
|
80
|
+
.withFunctionCall(argPaths, typeArgs);
|
|
81
|
+
} else if (ts.isCallExpression(expression)) {
|
|
82
|
+
// Chained call: func(arg1)(arg2)
|
|
83
|
+
const funcPath = buildCallPathFromSource(expression, context);
|
|
84
|
+
if (!funcPath) return null;
|
|
85
|
+
return funcPath.withFunctionCall(argPaths, typeArgs);
|
|
86
|
+
} else if (ts.isElementAccessExpression(expression)) {
|
|
87
|
+
// Element access call: obj[key](args)
|
|
88
|
+
const basePath = StructuredPath.fromNode(expression, context.sourceFile);
|
|
89
|
+
if (!basePath) return null;
|
|
90
|
+
return basePath.withFunctionCall(argPaths, typeArgs);
|
|
91
|
+
} else {
|
|
92
|
+
// Complex call expression
|
|
93
|
+
const basePath = StructuredPath.fromNode(expression, context.sourceFile);
|
|
94
|
+
if (!basePath) return null;
|
|
95
|
+
return basePath.withFunctionCall(argPaths, typeArgs);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
18
99
|
/**
|
|
19
100
|
* Checks if an expression is likely an array type.
|
|
20
101
|
* Uses TypeScript's type checker when available, falls back to heuristics.
|
|
@@ -113,9 +194,69 @@ export function markConditionVariablesAsNullable(
|
|
|
113
194
|
}
|
|
114
195
|
}
|
|
115
196
|
|
|
197
|
+
/**
|
|
198
|
+
* Helper to extract source location from an AST node
|
|
199
|
+
*/
|
|
200
|
+
function getSourceLocation(
|
|
201
|
+
node: ts.Node,
|
|
202
|
+
sourceFile: ts.SourceFile,
|
|
203
|
+
): ConditionalUsage['sourceLocation'] {
|
|
204
|
+
const start = node.getStart(sourceFile);
|
|
205
|
+
const { line, character } = sourceFile.getLineAndCharacterOfPosition(start);
|
|
206
|
+
const codeSnippet = node.getText(sourceFile);
|
|
207
|
+
|
|
208
|
+
return {
|
|
209
|
+
lineNumber: line + 1, // Convert to 1-based
|
|
210
|
+
column: character,
|
|
211
|
+
codeSnippet:
|
|
212
|
+
codeSnippet.length > 100
|
|
213
|
+
? codeSnippet.slice(0, 100) + '...'
|
|
214
|
+
: codeSnippet,
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Counts the number of conditions in an && chain (excluding JSX consequence)
|
|
220
|
+
*/
|
|
221
|
+
function countConditionsInAndChain(expr: ts.Expression): number {
|
|
222
|
+
const unwrapped = unwrapExpression(expr);
|
|
223
|
+
|
|
224
|
+
if (
|
|
225
|
+
ts.isBinaryExpression(unwrapped) &&
|
|
226
|
+
unwrapped.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken
|
|
227
|
+
) {
|
|
228
|
+
const leftCount = countConditionsInAndChain(unwrapped.left);
|
|
229
|
+
const rightUnwrapped = unwrapExpression(unwrapped.right);
|
|
230
|
+
const isJsxConsequence =
|
|
231
|
+
ts.isJsxElement(rightUnwrapped) ||
|
|
232
|
+
ts.isJsxSelfClosingElement(rightUnwrapped) ||
|
|
233
|
+
ts.isJsxFragment(rightUnwrapped);
|
|
234
|
+
|
|
235
|
+
if (isJsxConsequence) {
|
|
236
|
+
return leftCount;
|
|
237
|
+
}
|
|
238
|
+
return leftCount + countConditionsInAndChain(unwrapped.right);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Single condition (not an && chain)
|
|
242
|
+
return 1;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Chain tracking info for compound conditionals
|
|
247
|
+
*/
|
|
248
|
+
interface ChainInfo {
|
|
249
|
+
chainId: string;
|
|
250
|
+
chainLength: number;
|
|
251
|
+
chainExpression: string;
|
|
252
|
+
currentPosition: number;
|
|
253
|
+
compound: CompoundConditional;
|
|
254
|
+
}
|
|
255
|
+
|
|
116
256
|
/**
|
|
117
257
|
* Extracts conditional usages from a condition expression for key attribute detection.
|
|
118
258
|
* This function identifies which attributes are used in conditionals and how they're used.
|
|
259
|
+
* It also tracks compound conditionals (&&-chains) where all conditions must be true together.
|
|
119
260
|
*
|
|
120
261
|
* @param condition The condition expression to analyze
|
|
121
262
|
* @param context The analysis context
|
|
@@ -126,119 +267,236 @@ export function extractConditionalUsage(
|
|
|
126
267
|
context: AnalysisContext,
|
|
127
268
|
location: ConditionalUsage['location'],
|
|
128
269
|
): void {
|
|
129
|
-
|
|
270
|
+
// Internal recursive function with chain tracking
|
|
271
|
+
function extractWithChainTracking(
|
|
272
|
+
expr: ts.Expression,
|
|
273
|
+
chainInfo: ChainInfo | null,
|
|
274
|
+
isNegated: boolean,
|
|
275
|
+
): void {
|
|
276
|
+
const unwrapped = unwrapExpression(expr);
|
|
277
|
+
|
|
278
|
+
// Handle binary expressions with && (logical AND chains)
|
|
279
|
+
// Example: `a && b && <Component />` - both a and b are conditional checks
|
|
280
|
+
if (
|
|
281
|
+
ts.isBinaryExpression(unwrapped) &&
|
|
282
|
+
unwrapped.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken
|
|
283
|
+
) {
|
|
284
|
+
// Track if we're creating the chain at this level (root of the chain)
|
|
285
|
+
const isChainRoot = !chainInfo;
|
|
286
|
+
|
|
287
|
+
// If no chainInfo, this is the root of a new chain
|
|
288
|
+
if (isChainRoot) {
|
|
289
|
+
const chainLength = countConditionsInAndChain(unwrapped);
|
|
290
|
+
// Only create chain tracking for chains with 2+ conditions
|
|
291
|
+
if (chainLength >= 2) {
|
|
292
|
+
const chainId = `chain_${crypto.randomUUID().slice(0, 8)}`;
|
|
293
|
+
const chainExpression = unwrapped.getText(context.sourceFile);
|
|
294
|
+
const compound: CompoundConditional = {
|
|
295
|
+
chainId,
|
|
296
|
+
expression:
|
|
297
|
+
chainExpression.length > 200
|
|
298
|
+
? chainExpression.slice(0, 200) + '...'
|
|
299
|
+
: chainExpression,
|
|
300
|
+
conditions: [],
|
|
301
|
+
location,
|
|
302
|
+
sourceLocation: getSourceLocation(unwrapped, context.sourceFile),
|
|
303
|
+
};
|
|
304
|
+
chainInfo = {
|
|
305
|
+
chainId,
|
|
306
|
+
chainLength,
|
|
307
|
+
chainExpression: compound.expression,
|
|
308
|
+
currentPosition: 0,
|
|
309
|
+
compound,
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
}
|
|
130
313
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
if (
|
|
134
|
-
ts.isBinaryExpression(unwrapped) &&
|
|
135
|
-
unwrapped.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken
|
|
136
|
-
) {
|
|
137
|
-
// Recursively process left side
|
|
138
|
-
extractConditionalUsage(unwrapped.left, context, location);
|
|
314
|
+
// Recursively process left side
|
|
315
|
+
extractWithChainTracking(unwrapped.left, chainInfo, false);
|
|
139
316
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
317
|
+
// Process right side if it's not JSX (JSX is the consequence, not the condition)
|
|
318
|
+
const rightUnwrapped = unwrapExpression(unwrapped.right);
|
|
319
|
+
const isJsxConsequence =
|
|
320
|
+
ts.isJsxElement(rightUnwrapped) ||
|
|
321
|
+
ts.isJsxSelfClosingElement(rightUnwrapped) ||
|
|
322
|
+
ts.isJsxFragment(rightUnwrapped);
|
|
146
323
|
|
|
147
|
-
|
|
148
|
-
|
|
324
|
+
if (!isJsxConsequence) {
|
|
325
|
+
extractWithChainTracking(unwrapped.right, chainInfo, false);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
// If this is the root of the chain, register the compound conditional
|
|
329
|
+
if (isChainRoot && chainInfo) {
|
|
330
|
+
context.addCompoundConditional(chainInfo.compound);
|
|
331
|
+
}
|
|
332
|
+
return;
|
|
149
333
|
}
|
|
150
|
-
return;
|
|
151
|
-
}
|
|
152
334
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
335
|
+
// Handle binary expressions with || (logical OR)
|
|
336
|
+
// OR breaks the chain - each side is independent
|
|
337
|
+
if (
|
|
338
|
+
ts.isBinaryExpression(unwrapped) &&
|
|
339
|
+
unwrapped.operatorToken.kind === ts.SyntaxKind.BarBarToken
|
|
340
|
+
) {
|
|
341
|
+
// Both sides of || are independent conditional checks (no chain tracking)
|
|
342
|
+
extractWithChainTracking(unwrapped.left, null, false);
|
|
343
|
+
extractWithChainTracking(unwrapped.right, null, false);
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
163
346
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
347
|
+
// Handle comparison operators (===, !==, <, >, <=, >=)
|
|
348
|
+
// Example: `if (status === 'active')` - status is compared against 'active'
|
|
349
|
+
if (
|
|
350
|
+
ts.isBinaryExpression(unwrapped) &&
|
|
351
|
+
isComparisonOperator(unwrapped.operatorToken.kind)
|
|
352
|
+
) {
|
|
353
|
+
// Try to extract the variable and the compared value
|
|
354
|
+
const leftPath = StructuredPath.fromNode(
|
|
355
|
+
unwrapped.left,
|
|
356
|
+
context.sourceFile,
|
|
357
|
+
);
|
|
358
|
+
const rightPath = StructuredPath.fromNode(
|
|
359
|
+
unwrapped.right,
|
|
360
|
+
context.sourceFile,
|
|
361
|
+
);
|
|
179
362
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
363
|
+
// Determine the compared value for computing requiredValue
|
|
364
|
+
const getRequiredValue = (
|
|
365
|
+
literalValue: string | undefined,
|
|
366
|
+
isNegatedComparison: boolean,
|
|
367
|
+
): string | boolean | undefined => {
|
|
368
|
+
if (literalValue === undefined) return undefined;
|
|
369
|
+
// For !== comparisons, the condition is true when NOT equal to the value
|
|
370
|
+
// For === comparisons, the condition is true when equal to the value
|
|
371
|
+
const isNotEqual =
|
|
372
|
+
unwrapped.operatorToken.kind ===
|
|
373
|
+
ts.SyntaxKind.ExclamationEqualsEqualsToken ||
|
|
374
|
+
unwrapped.operatorToken.kind === ts.SyntaxKind.ExclamationEqualsToken;
|
|
375
|
+
if (isNotEqual) {
|
|
376
|
+
// !== 'value' means requiredValue is NOT 'value', but we express this as "not 'value'"
|
|
377
|
+
return `not ${literalValue}`;
|
|
378
|
+
}
|
|
379
|
+
return literalValue;
|
|
380
|
+
};
|
|
381
|
+
|
|
382
|
+
// Helper to add a condition
|
|
383
|
+
const addCondition = (
|
|
384
|
+
path: string,
|
|
385
|
+
conditionType: 'comparison' | 'truthiness',
|
|
386
|
+
comparedValues?: string[],
|
|
387
|
+
requiredValue?: string | boolean,
|
|
388
|
+
) => {
|
|
389
|
+
const usage: ConditionalUsage = {
|
|
390
|
+
path,
|
|
391
|
+
conditionType,
|
|
392
|
+
comparedValues,
|
|
393
|
+
location,
|
|
394
|
+
sourceLocation: getSourceLocation(unwrapped, context.sourceFile),
|
|
395
|
+
isNegated,
|
|
396
|
+
};
|
|
397
|
+
|
|
398
|
+
// Add chain info if part of a compound conditional
|
|
399
|
+
if (chainInfo) {
|
|
400
|
+
usage.chainId = chainInfo.chainId;
|
|
401
|
+
usage.chainPosition = chainInfo.currentPosition;
|
|
402
|
+
usage.chainLength = chainInfo.chainLength;
|
|
403
|
+
usage.chainExpression = chainInfo.chainExpression;
|
|
404
|
+
chainInfo.currentPosition++;
|
|
405
|
+
|
|
406
|
+
// Add to compound conditional conditions
|
|
407
|
+
chainInfo.compound.conditions.push({
|
|
408
|
+
path,
|
|
409
|
+
conditionType,
|
|
410
|
+
comparedValues,
|
|
411
|
+
isNegated,
|
|
412
|
+
requiredValue,
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
context.addConditionalUsage(usage);
|
|
417
|
+
};
|
|
418
|
+
|
|
419
|
+
// Check if left is a variable and right is a literal
|
|
420
|
+
if (leftPath && isLiteralExpression(unwrapped.right)) {
|
|
421
|
+
const literalValue = getLiteralValue(unwrapped.right, context);
|
|
422
|
+
addCondition(
|
|
423
|
+
leftPath.toLeftHandSideString(),
|
|
424
|
+
'comparison',
|
|
425
|
+
literalValue !== undefined ? [literalValue] : undefined,
|
|
426
|
+
getRequiredValue(literalValue, isNegated),
|
|
427
|
+
);
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
// Check if right is a variable and left is a literal
|
|
432
|
+
if (rightPath && isLiteralExpression(unwrapped.left)) {
|
|
433
|
+
const literalValue = getLiteralValue(unwrapped.left, context);
|
|
434
|
+
addCondition(
|
|
435
|
+
rightPath.toLeftHandSideString(),
|
|
436
|
+
'comparison',
|
|
437
|
+
literalValue !== undefined ? [literalValue] : undefined,
|
|
438
|
+
getRequiredValue(literalValue, isNegated),
|
|
439
|
+
);
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
// Both sides are variables - record both as comparisons without specific values
|
|
444
|
+
if (leftPath) {
|
|
445
|
+
addCondition(leftPath.toLeftHandSideString(), 'comparison');
|
|
446
|
+
}
|
|
447
|
+
if (rightPath) {
|
|
448
|
+
addCondition(rightPath.toLeftHandSideString(), 'comparison');
|
|
449
|
+
}
|
|
189
450
|
return;
|
|
190
451
|
}
|
|
191
452
|
|
|
192
|
-
//
|
|
193
|
-
if (
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
location,
|
|
200
|
-
});
|
|
453
|
+
// Handle prefix unary NOT expression: !variable
|
|
454
|
+
// Example: `if (!isVisible)` - isVisible is a truthiness check (negated)
|
|
455
|
+
if (
|
|
456
|
+
ts.isPrefixUnaryExpression(unwrapped) &&
|
|
457
|
+
unwrapped.operator === ts.SyntaxKind.ExclamationToken
|
|
458
|
+
) {
|
|
459
|
+
extractWithChainTracking(unwrapped.operand, chainInfo, !isNegated);
|
|
201
460
|
return;
|
|
202
461
|
}
|
|
203
462
|
|
|
204
|
-
//
|
|
205
|
-
if (
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
if (rightPath) {
|
|
213
|
-
context.addConditionalUsage({
|
|
214
|
-
path: rightPath.toLeftHandSideString(),
|
|
215
|
-
conditionType: 'comparison',
|
|
463
|
+
// Handle simple identifiers or property accesses (truthiness checks)
|
|
464
|
+
// Example: `if (x)` or `x && <JSX />` - x is checked for truthiness
|
|
465
|
+
const path = StructuredPath.fromNode(unwrapped, context.sourceFile);
|
|
466
|
+
if (path && !path.isLiteral()) {
|
|
467
|
+
const pathStr = path.toLeftHandSideString();
|
|
468
|
+
const usage: ConditionalUsage = {
|
|
469
|
+
path: pathStr,
|
|
470
|
+
conditionType: 'truthiness',
|
|
216
471
|
location,
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
472
|
+
sourceLocation: getSourceLocation(unwrapped, context.sourceFile),
|
|
473
|
+
isNegated,
|
|
474
|
+
};
|
|
475
|
+
|
|
476
|
+
// Add chain info if part of a compound conditional
|
|
477
|
+
if (chainInfo) {
|
|
478
|
+
usage.chainId = chainInfo.chainId;
|
|
479
|
+
usage.chainPosition = chainInfo.currentPosition;
|
|
480
|
+
usage.chainLength = chainInfo.chainLength;
|
|
481
|
+
usage.chainExpression = chainInfo.chainExpression;
|
|
482
|
+
chainInfo.currentPosition++;
|
|
483
|
+
|
|
484
|
+
// Add to compound conditional conditions
|
|
485
|
+
// For truthiness, requiredValue is true if not negated, false if negated
|
|
486
|
+
chainInfo.compound.conditions.push({
|
|
487
|
+
path: pathStr,
|
|
488
|
+
conditionType: 'truthiness',
|
|
489
|
+
isNegated,
|
|
490
|
+
requiredValue: !isNegated,
|
|
491
|
+
});
|
|
492
|
+
}
|
|
221
493
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
if (
|
|
225
|
-
ts.isPrefixUnaryExpression(unwrapped) &&
|
|
226
|
-
unwrapped.operator === ts.SyntaxKind.ExclamationToken
|
|
227
|
-
) {
|
|
228
|
-
extractConditionalUsage(unwrapped.operand, context, location);
|
|
229
|
-
return;
|
|
494
|
+
context.addConditionalUsage(usage);
|
|
495
|
+
}
|
|
230
496
|
}
|
|
231
497
|
|
|
232
|
-
//
|
|
233
|
-
|
|
234
|
-
const path = StructuredPath.fromNode(unwrapped, context.sourceFile);
|
|
235
|
-
if (path && !path.isLiteral()) {
|
|
236
|
-
context.addConditionalUsage({
|
|
237
|
-
path: path.toLeftHandSideString(),
|
|
238
|
-
conditionType: 'truthiness',
|
|
239
|
-
location,
|
|
240
|
-
});
|
|
241
|
-
}
|
|
498
|
+
// Start extraction with no chain info
|
|
499
|
+
extractWithChainTracking(condition, null, false);
|
|
242
500
|
}
|
|
243
501
|
|
|
244
502
|
/**
|
|
@@ -341,7 +599,16 @@ export function processExpression({
|
|
|
341
599
|
) {
|
|
342
600
|
markConditionVariablesAsNullable(unwrappedNode, context);
|
|
343
601
|
// Extract conditional usages for key attribute detection
|
|
344
|
-
|
|
602
|
+
// Only call from the OUTERMOST && expression to avoid duplicates
|
|
603
|
+
// Check if parent is also a && (meaning we're nested)
|
|
604
|
+
const parent = unwrappedNode.parent;
|
|
605
|
+
const parentIsAndChain =
|
|
606
|
+
parent &&
|
|
607
|
+
ts.isBinaryExpression(parent) &&
|
|
608
|
+
parent.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken;
|
|
609
|
+
if (!parentIsAndChain) {
|
|
610
|
+
extractConditionalUsage(unwrappedNode, context, 'logical-and');
|
|
611
|
+
}
|
|
345
612
|
}
|
|
346
613
|
|
|
347
614
|
// If the node falls within an excluded child scope, stop processing it.
|
|
@@ -930,9 +1197,10 @@ export function processExpression({
|
|
|
930
1197
|
return false;
|
|
931
1198
|
}
|
|
932
1199
|
|
|
933
|
-
//
|
|
934
|
-
//
|
|
935
|
-
|
|
1200
|
+
// Build call path using original source text for consistent schema paths.
|
|
1201
|
+
// IMPORTANT: Never use cyScope names in call paths - they are internal identifiers
|
|
1202
|
+
// that should not appear in schema paths or call signatures.
|
|
1203
|
+
const callPath = buildCallPathFromSource(unwrappedNode, context);
|
|
936
1204
|
|
|
937
1205
|
// 2. Process all arguments recursively WITH targetPath for proper equivalence
|
|
938
1206
|
for (let i = 0; i < unwrappedNode.arguments.length; i++) {
|
|
@@ -1099,6 +1367,13 @@ export function processExpression({
|
|
|
1099
1367
|
// Create a path for this property within the base
|
|
1100
1368
|
const propPath = targetPath.withProperty(propName);
|
|
1101
1369
|
|
|
1370
|
+
// Handle child boundaries (callback functions) in object properties
|
|
1371
|
+
// This establishes equivalency between the property path and the child scope
|
|
1372
|
+
// e.g., columns[0].renderCell → cyScope1()
|
|
1373
|
+
if (context.isChildBoundary(property.initializer)) {
|
|
1374
|
+
context.addChildBoundaryEquivalence(propPath, property.initializer);
|
|
1375
|
+
}
|
|
1376
|
+
|
|
1102
1377
|
// Process the property value with propPath as targetPath
|
|
1103
1378
|
// This allows nested object literals to work correctly
|
|
1104
1379
|
processExpression({
|
|
@@ -1404,8 +1679,13 @@ export function processExpression({
|
|
|
1404
1679
|
context,
|
|
1405
1680
|
typeHint: 'boolean | unknown',
|
|
1406
1681
|
}); //TODO: could we capture that this is evidence of a boolean type?
|
|
1407
|
-
|
|
1408
|
-
|
|
1682
|
+
|
|
1683
|
+
// Process both branches WITH targetPath to establish equivalencies
|
|
1684
|
+
// This is critical for tracing nested properties through ternary assignments
|
|
1685
|
+
// e.g., const items = condition ? arr1 : arr2; items.map(i => i.prop)
|
|
1686
|
+
// We need items to be equivalent to both arr1 AND arr2 for proper tracing
|
|
1687
|
+
processExpression({ node: unwrappedNode.whenTrue, context, targetPath });
|
|
1688
|
+
processExpression({ node: unwrappedNode.whenFalse, context, targetPath });
|
|
1409
1689
|
|
|
1410
1690
|
// Create a path for the whole expression
|
|
1411
1691
|
const expressionSourcePath = nodeToSource(
|
|
@@ -1428,10 +1708,22 @@ export function processExpression({
|
|
|
1428
1708
|
// Register type for the expression
|
|
1429
1709
|
context.addType(expressionSourcePath, resultType);
|
|
1430
1710
|
|
|
1431
|
-
// If targetPath is provided,
|
|
1711
|
+
// If targetPath is provided, only register type (don't overwrite branch equivalencies)
|
|
1712
|
+
// The equivalencies to individual branches (set above) are more useful for tracing
|
|
1713
|
+
// than an equivalency to the entire ternary expression text
|
|
1432
1714
|
if (targetPath) {
|
|
1433
|
-
|
|
1434
|
-
|
|
1715
|
+
// NOTE: We intentionally do NOT add equivalence here.
|
|
1716
|
+
// The branch processing above already added equivalencies:
|
|
1717
|
+
// targetPath -> whenTrue branch
|
|
1718
|
+
// targetPath -> whenFalse branch
|
|
1719
|
+
// Adding an equivalence to expressionSourcePath would overwrite those
|
|
1720
|
+
// with a useless equivalence to the ternary text itself.
|
|
1721
|
+
//
|
|
1722
|
+
// Use updateSchemaType instead of addType because:
|
|
1723
|
+
// 1. Branch processing may have already set a type on targetPath
|
|
1724
|
+
// 2. addType has a guard that prevents overwriting specific types with 'unknown'
|
|
1725
|
+
// 3. updateSchemaType bypasses this guard, ensuring the ternary's computed type is used
|
|
1726
|
+
context.updateSchemaType(targetPath, resultType);
|
|
1435
1727
|
}
|
|
1436
1728
|
|
|
1437
1729
|
return true;
|
|
@@ -2232,6 +2524,9 @@ function processJsxAttribute(
|
|
|
2232
2524
|
if (ts.isJsxExpression(attr.initializer) && attr.initializer.expression) {
|
|
2233
2525
|
const expression = attr.initializer.expression;
|
|
2234
2526
|
if (context.isChildBoundary(expression)) {
|
|
2527
|
+
// Create equivalency between attribute path and child scope
|
|
2528
|
+
// e.g., Grid().signature[0].renderRow → cyScope1()
|
|
2529
|
+
context.addChildBoundaryEquivalence(attributePath, expression);
|
|
2235
2530
|
return true;
|
|
2236
2531
|
}
|
|
2237
2532
|
|
|
@@ -159,6 +159,9 @@ export interface AstScopeAnalysisResult {
|
|
|
159
159
|
// Maps attribute path to array of conditional usages
|
|
160
160
|
conditionalUsages: Record<string, ConditionalUsage[]>;
|
|
161
161
|
|
|
162
|
+
// Compound conditionals grouped by chain (all conditions must be true together)
|
|
163
|
+
compoundConditionals?: CompoundConditional[];
|
|
164
|
+
|
|
162
165
|
// Whether the analysis is complete enough to skip LLM calls
|
|
163
166
|
isComplete: boolean;
|
|
164
167
|
|
|
@@ -191,6 +194,57 @@ export interface ConditionalUsage {
|
|
|
191
194
|
* Where this conditional usage occurs
|
|
192
195
|
*/
|
|
193
196
|
location: 'if' | 'ternary' | 'logical-and' | 'switch';
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Source location information for this conditional usage
|
|
200
|
+
*/
|
|
201
|
+
sourceLocation?: {
|
|
202
|
+
/** Line number (1-based) */
|
|
203
|
+
lineNumber: number;
|
|
204
|
+
/** Column number (0-based) */
|
|
205
|
+
column: number;
|
|
206
|
+
/** The code snippet containing this conditional */
|
|
207
|
+
codeSnippet: string;
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
/** Unique ID for this compound conditional chain (shared by all conditions in same && chain) */
|
|
211
|
+
chainId?: string;
|
|
212
|
+
/** Position in the chain (0 = leftmost) */
|
|
213
|
+
chainPosition?: number;
|
|
214
|
+
/** Total number of conditions in this chain */
|
|
215
|
+
chainLength?: number;
|
|
216
|
+
/** The full original expression (e.g., "a && b && c") */
|
|
217
|
+
chainExpression?: string;
|
|
218
|
+
/** Whether this condition is negated (e.g., !foo) */
|
|
219
|
+
isNegated?: boolean;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Represents a compound conditional (e.g., a && b && c) where all conditions
|
|
224
|
+
* must be satisfied together for a code path to execute.
|
|
225
|
+
*/
|
|
226
|
+
export interface CompoundConditional {
|
|
227
|
+
/** Unique identifier for this compound conditional */
|
|
228
|
+
chainId: string;
|
|
229
|
+
/** The full expression (e.g., "scenarios.length > 0 && !displayState.isQueued") */
|
|
230
|
+
expression: string;
|
|
231
|
+
/** Individual conditions in order */
|
|
232
|
+
conditions: {
|
|
233
|
+
path: string;
|
|
234
|
+
conditionType: 'truthiness' | 'comparison' | 'switch';
|
|
235
|
+
comparedValues?: string[];
|
|
236
|
+
isNegated: boolean;
|
|
237
|
+
/** Required value for this condition to be true */
|
|
238
|
+
requiredValue?: string | boolean;
|
|
239
|
+
}[];
|
|
240
|
+
/** Where this compound conditional occurs */
|
|
241
|
+
location: 'if' | 'ternary' | 'logical-and' | 'switch';
|
|
242
|
+
/** Source location for the entire compound expression */
|
|
243
|
+
sourceLocation: {
|
|
244
|
+
lineNumber: number;
|
|
245
|
+
column: number;
|
|
246
|
+
codeSnippet: string;
|
|
247
|
+
};
|
|
194
248
|
}
|
|
195
249
|
|
|
196
250
|
/**
|
|
@@ -318,6 +372,12 @@ export interface AnalysisContext {
|
|
|
318
372
|
// Get all conditional usages
|
|
319
373
|
getConditionalUsages(): Record<string, ConditionalUsage[]>;
|
|
320
374
|
|
|
375
|
+
// Add a compound conditional for key attribute dependency detection
|
|
376
|
+
addCompoundConditional(compound: CompoundConditional): void;
|
|
377
|
+
|
|
378
|
+
// Get all compound conditionals
|
|
379
|
+
getCompoundConditionals(): CompoundConditional[];
|
|
380
|
+
|
|
321
381
|
// Update a schema type, typically used when switch statements reveal
|
|
322
382
|
// the valid values for a parameter (creating a union type)
|
|
323
383
|
updateSchemaType(path: string | StructuredPath, newType: string): void;
|