@codeyam/codeyam-cli 0.1.0-staging.15d0f46 → 0.1.0-staging.1669d45
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/common/execAsync.ts +1 -1
- package/analyzer-template/log.txt +3 -3
- package/analyzer-template/package.json +9 -5
- package/analyzer-template/packages/ai/index.ts +5 -3
- package/analyzer-template/packages/ai/package.json +1 -1
- package/analyzer-template/packages/ai/src/lib/__mocks__/completionCall.ts +122 -0
- package/analyzer-template/packages/ai/src/lib/analyzeScope.ts +152 -6
- package/analyzer-template/packages/ai/src/lib/astScopes/astScopeAnalyzer.ts +107 -1
- package/analyzer-template/packages/ai/src/lib/astScopes/conditionalEffectsExtractor.ts +644 -0
- package/analyzer-template/packages/ai/src/lib/astScopes/methodSemantics.ts +42 -0
- package/analyzer-template/packages/ai/src/lib/astScopes/patterns/ifStatementHandler.ts +18 -0
- package/analyzer-template/packages/ai/src/lib/astScopes/patterns/switchStatementHandler.ts +38 -1
- package/analyzer-template/packages/ai/src/lib/astScopes/patterns/variableDeclarationHandler.ts +301 -1
- package/analyzer-template/packages/ai/src/lib/astScopes/processExpression.ts +972 -106
- package/analyzer-template/packages/ai/src/lib/astScopes/types.ts +232 -0
- package/analyzer-template/packages/ai/src/lib/checkAllAttributes.ts +29 -10
- package/analyzer-template/packages/ai/src/lib/completionCall.ts +18 -2
- package/analyzer-template/packages/ai/src/lib/dataStructure/ScopeDataStructure.ts +1409 -138
- 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 +771 -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 +39 -4
- 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 +42 -2
- package/analyzer-template/packages/ai/src/lib/deepEqual.ts +30 -0
- package/analyzer-template/packages/ai/src/lib/generateChangesEntityScenarioData.ts +74 -7
- package/analyzer-template/packages/ai/src/lib/generateChangesEntityScenarios.ts +89 -112
- package/analyzer-template/packages/ai/src/lib/generateEntityDataStructure.ts +6 -0
- package/analyzer-template/packages/ai/src/lib/generateEntityScenarioData.ts +486 -86
- package/analyzer-template/packages/ai/src/lib/generateEntityScenarios.ts +182 -104
- package/analyzer-template/packages/ai/src/lib/generateExecutionFlows.ts +201 -0
- package/analyzer-template/packages/ai/src/lib/generateExecutionFlowsFromConditionalEffects.ts +528 -0
- package/analyzer-template/packages/ai/src/lib/generateExecutionFlowsFromConditionals.ts +1019 -0
- 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/isolateScopes.ts +276 -3
- package/analyzer-template/packages/ai/src/lib/mergeStatements.ts +33 -3
- package/analyzer-template/packages/ai/src/lib/promptGenerators/gatherAttributesMap.ts +7 -0
- package/analyzer-template/packages/ai/src/lib/promptGenerators/generateChangesEntityScenarioDataGenerator.ts +1 -1
- package/analyzer-template/packages/ai/src/lib/promptGenerators/generateChangesEntityScenariosGenerator.ts +32 -102
- package/analyzer-template/packages/ai/src/lib/promptGenerators/generateEntityScenarioDataGenerator.ts +71 -4
- package/analyzer-template/packages/ai/src/lib/promptGenerators/generateEntityScenariosGenerator.ts +14 -53
- package/analyzer-template/packages/ai/src/lib/promptGenerators/generateMissingKeysPrompt.ts +58 -0
- package/analyzer-template/packages/ai/src/lib/promptGenerators/guessNewScenarioDataFromDescriptionGenerator.ts +28 -2
- package/analyzer-template/packages/ai/src/lib/resolvePathToControllable.ts +690 -0
- package/analyzer-template/packages/ai/src/lib/splitOutsideParentheses.ts +5 -1
- package/analyzer-template/packages/ai/src/lib/validateExecutionFlowPaths.ts +531 -0
- package/analyzer-template/packages/ai/src/lib/worker/SerializableDataStructure.ts +102 -0
- package/analyzer-template/packages/ai/src/lib/worker/analyzeScopeWorker.ts +8 -1
- package/analyzer-template/packages/analyze/src/lib/FileAnalyzer.ts +14 -0
- package/analyzer-template/packages/analyze/src/lib/asts/nodes/index.ts +1 -0
- package/analyzer-template/packages/analyze/src/lib/asts/nodes/isAsyncFunction.ts +67 -0
- package/analyzer-template/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.ts +458 -267
- package/analyzer-template/packages/analyze/src/lib/files/analyze/analyzeEntities.ts +18 -0
- package/analyzer-template/packages/analyze/src/lib/files/analyze/findOrCreateEntity.ts +3 -0
- package/analyzer-template/packages/analyze/src/lib/files/analyzeChange.ts +31 -15
- package/analyzer-template/packages/analyze/src/lib/files/analyzeEntity.ts +11 -7
- package/analyzer-template/packages/analyze/src/lib/files/analyzeInitial.ts +11 -12
- package/analyzer-template/packages/analyze/src/lib/files/enums/steps.ts +1 -1
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/enrichArrayTypesFromChildSignatures.ts +196 -0
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/enrichUnknownTypesFromSourceEquivalencies.ts +102 -0
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.ts +588 -52
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateChangesScenarioData.ts +1 -1
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateChangesScenarios.ts +28 -62
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateDataStructure.ts +299 -133
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateExecutionFlows.ts +156 -0
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateScenarioData.ts +78 -83
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateScenarios.ts +4 -8
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.ts +384 -94
- package/analyzer-template/packages/aws/codebuild/index.ts +1 -0
- package/analyzer-template/packages/aws/dist/src/lib/codebuild/waitForBuild.d.ts +11 -1
- package/analyzer-template/packages/aws/dist/src/lib/codebuild/waitForBuild.d.ts.map +1 -1
- package/analyzer-template/packages/aws/dist/src/lib/codebuild/waitForBuild.js +29 -18
- package/analyzer-template/packages/aws/dist/src/lib/codebuild/waitForBuild.js.map +1 -1
- package/analyzer-template/packages/aws/dist/src/lib/ecs/ecsDefineContainer.d.ts +2 -2
- package/analyzer-template/packages/aws/dist/src/lib/ecs/ecsDefineContainer.d.ts.map +1 -1
- package/analyzer-template/packages/aws/dist/src/lib/ecs/ecsDefineContainer.js +2 -2
- package/analyzer-template/packages/aws/dist/src/lib/ecs/ecsDefineContainer.js.map +1 -1
- package/analyzer-template/packages/aws/dist/src/lib/ecs/ecsTaskFactory.d.ts +8 -18
- package/analyzer-template/packages/aws/dist/src/lib/ecs/ecsTaskFactory.d.ts.map +1 -1
- package/analyzer-template/packages/aws/dist/src/lib/ecs/ecsTaskFactory.js +17 -61
- package/analyzer-template/packages/aws/dist/src/lib/ecs/ecsTaskFactory.js.map +1 -1
- 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/dist/src/lib/s3/uploadFileToS3.d.ts.map +1 -1
- package/analyzer-template/packages/aws/dist/src/lib/s3/uploadFileToS3.js +8 -1
- package/analyzer-template/packages/aws/dist/src/lib/s3/uploadFileToS3.js.map +1 -1
- package/analyzer-template/packages/aws/package.json +2 -2
- package/analyzer-template/packages/aws/s3/index.ts +1 -0
- package/analyzer-template/packages/aws/src/lib/codebuild/waitForBuild.ts +43 -19
- package/analyzer-template/packages/aws/src/lib/ecs/ecsDefineContainer.ts +3 -3
- package/analyzer-template/packages/aws/src/lib/ecs/ecsTaskFactory.ts +17 -69
- package/analyzer-template/packages/aws/src/lib/s3/checkS3ObjectExists.ts +47 -0
- package/analyzer-template/packages/aws/src/lib/s3/uploadFileToS3.ts +8 -1
- 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 +36 -9
- package/analyzer-template/packages/database/src/lib/loadReadyToBeCapturedAnalyses.ts +7 -3
- package/analyzer-template/packages/generate/index.ts +3 -0
- package/analyzer-template/packages/generate/src/lib/componentScenarioPage/componentScenarioPageNext.ts +17 -1
- package/analyzer-template/packages/generate/src/lib/componentScenarioPage/generateScenarioClientWrapper.ts +193 -0
- package/analyzer-template/packages/generate/src/lib/componentScenarioPage/generateScenarioServerComponent.ts +73 -0
- 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/scenarioComponentForServer.ts +114 -0
- 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 +1 -11
- 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 +30 -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/entitiesTable.d.ts +1 -0
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/entitiesTable.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/scenariosTable.d.ts +2 -6
- 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 +7 -4
- package/analyzer-template/packages/github/dist/database/src/lib/loadReadyToBeCapturedAnalyses.js.map +1 -1
- package/analyzer-template/packages/github/dist/generate/index.d.ts +3 -0
- package/analyzer-template/packages/github/dist/generate/index.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/generate/index.js +3 -0
- package/analyzer-template/packages/github/dist/generate/index.js.map +1 -1
- package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/componentScenarioPageNext.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/componentScenarioPageNext.js +16 -1
- package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/componentScenarioPageNext.js.map +1 -1
- package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/generateScenarioClientWrapper.d.ts +9 -0
- package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/generateScenarioClientWrapper.d.ts.map +1 -0
- package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/generateScenarioClientWrapper.js +189 -0
- package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/generateScenarioClientWrapper.js.map +1 -0
- package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/generateScenarioServerComponent.d.ts +20 -0
- package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/generateScenarioServerComponent.d.ts.map +1 -0
- package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/generateScenarioServerComponent.js +53 -0
- package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/generateScenarioServerComponent.js.map +1 -0
- 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/scenarioComponentForServer.d.ts +8 -0
- package/analyzer-template/packages/github/dist/generate/src/lib/scenarioComponentForServer.d.ts.map +1 -0
- package/analyzer-template/packages/github/dist/generate/src/lib/scenarioComponentForServer.js +89 -0
- package/analyzer-template/packages/github/dist/generate/src/lib/scenarioComponentForServer.js.map +1 -0
- package/analyzer-template/packages/github/dist/github/src/lib/loadOrCreateCommit.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/github/src/lib/loadOrCreateCommit.js +10 -0
- package/analyzer-template/packages/github/dist/github/src/lib/loadOrCreateCommit.js.map +1 -1
- package/analyzer-template/packages/github/dist/github/src/lib/syncPrimaryBranch.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/github/src/lib/syncPrimaryBranch.js +3 -0
- package/analyzer-template/packages/github/dist/github/src/lib/syncPrimaryBranch.js.map +1 -1
- package/analyzer-template/packages/github/dist/types/index.d.ts +2 -2
- package/analyzer-template/packages/github/dist/types/index.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/types/index.js.map +1 -1
- package/analyzer-template/packages/github/dist/types/src/types/Analysis.d.ts +63 -13
- package/analyzer-template/packages/github/dist/types/src/types/Analysis.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/types/src/types/Entity.d.ts +2 -0
- package/analyzer-template/packages/github/dist/types/src/types/Entity.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/types/src/types/Scenario.d.ts +11 -6
- package/analyzer-template/packages/github/dist/types/src/types/Scenario.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/types/src/types/ScenariosDataStructure.d.ts +146 -0
- package/analyzer-template/packages/github/dist/types/src/types/ScenariosDataStructure.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/types/src/types/StatementInfo.d.ts +2 -0
- package/analyzer-template/packages/github/dist/types/src/types/StatementInfo.d.ts.map +1 -1
- package/analyzer-template/packages/github/src/lib/loadOrCreateCommit.ts +14 -0
- package/analyzer-template/packages/github/src/lib/syncPrimaryBranch.ts +2 -0
- package/analyzer-template/packages/process/index.ts +2 -0
- package/analyzer-template/packages/process/package.json +12 -0
- package/analyzer-template/packages/process/tsconfig.json +8 -0
- package/analyzer-template/packages/types/index.ts +4 -0
- package/analyzer-template/packages/types/src/types/Analysis.ts +79 -13
- package/analyzer-template/packages/types/src/types/Entity.ts +2 -0
- package/analyzer-template/packages/types/src/types/Scenario.ts +11 -10
- package/analyzer-template/packages/types/src/types/ScenariosDataStructure.ts +161 -0
- package/analyzer-template/packages/types/src/types/StatementInfo.ts +2 -0
- package/analyzer-template/packages/utils/dist/types/index.d.ts +2 -2
- package/analyzer-template/packages/utils/dist/types/index.d.ts.map +1 -1
- package/analyzer-template/packages/utils/dist/types/index.js.map +1 -1
- package/analyzer-template/packages/utils/dist/types/src/types/Analysis.d.ts +63 -13
- package/analyzer-template/packages/utils/dist/types/src/types/Analysis.d.ts.map +1 -1
- package/analyzer-template/packages/utils/dist/types/src/types/Entity.d.ts +2 -0
- package/analyzer-template/packages/utils/dist/types/src/types/Entity.d.ts.map +1 -1
- package/analyzer-template/packages/utils/dist/types/src/types/Scenario.d.ts +11 -6
- package/analyzer-template/packages/utils/dist/types/src/types/Scenario.d.ts.map +1 -1
- package/analyzer-template/packages/utils/dist/types/src/types/ScenariosDataStructure.d.ts +146 -0
- package/analyzer-template/packages/utils/dist/types/src/types/ScenariosDataStructure.d.ts.map +1 -1
- package/analyzer-template/packages/utils/dist/types/src/types/StatementInfo.d.ts +2 -0
- package/analyzer-template/packages/utils/dist/types/src/types/StatementInfo.d.ts.map +1 -1
- package/analyzer-template/playwright/capture.ts +37 -18
- package/analyzer-template/playwright/getCodeYamInfo.ts +12 -7
- package/analyzer-template/playwright/takeElementScreenshot.ts +26 -11
- package/analyzer-template/playwright/waitForServer.ts +21 -6
- package/analyzer-template/project/analyzeBaselineCommit.ts +4 -0
- package/analyzer-template/project/analyzeBranchCommit.ts +4 -0
- package/analyzer-template/project/analyzeFileEntities.ts +4 -0
- package/analyzer-template/project/analyzeRegularCommit.ts +4 -0
- package/analyzer-template/project/constructMockCode.ts +868 -132
- package/analyzer-template/project/controller/startController.ts +16 -1
- package/analyzer-template/project/executeLibraryFunctionDirect.ts +7 -3
- package/analyzer-template/project/mocks/analyzeFileMock.ts +8 -7
- package/analyzer-template/project/orchestrateCapture/KyselyAnalysisLoader.ts +3 -6
- package/analyzer-template/project/orchestrateCapture/SequentialCaptureTaskRunner.ts +49 -33
- package/analyzer-template/project/orchestrateCapture.ts +10 -3
- package/analyzer-template/project/reconcileMockDataKeys.ts +102 -2
- package/analyzer-template/project/runAnalysis.ts +7 -0
- package/analyzer-template/project/serverOnlyModules.ts +127 -2
- package/analyzer-template/project/start.ts +26 -4
- package/analyzer-template/project/startScenarioCapture.ts +72 -40
- package/analyzer-template/project/writeMockDataTsx.ts +118 -55
- package/analyzer-template/project/writeScenarioClientWrapper.ts +21 -0
- package/analyzer-template/project/writeScenarioComponents.ts +263 -92
- package/analyzer-template/project/writeScenarioFiles.ts +26 -0
- package/analyzer-template/project/writeSimpleRoot.ts +13 -15
- package/analyzer-template/scripts/comboWorkerLoop.cjs +1 -0
- package/analyzer-template/scripts/defaultCmd.sh +9 -0
- package/analyzer-template/tsconfig.json +2 -1
- package/background/src/lib/local/createLocalAnalyzer.js +1 -29
- package/background/src/lib/local/createLocalAnalyzer.js.map +1 -1
- package/background/src/lib/local/execAsync.js +1 -1
- package/background/src/lib/local/execAsync.js.map +1 -1
- package/background/src/lib/virtualized/common/execAsync.js +1 -1
- package/background/src/lib/virtualized/common/execAsync.js.map +1 -1
- package/background/src/lib/virtualized/project/analyzeBaselineCommit.js +2 -1
- package/background/src/lib/virtualized/project/analyzeBaselineCommit.js.map +1 -1
- package/background/src/lib/virtualized/project/analyzeBranchCommit.js +2 -1
- package/background/src/lib/virtualized/project/analyzeBranchCommit.js.map +1 -1
- package/background/src/lib/virtualized/project/analyzeFileEntities.js +2 -1
- package/background/src/lib/virtualized/project/analyzeFileEntities.js.map +1 -1
- package/background/src/lib/virtualized/project/analyzeRegularCommit.js +2 -1
- package/background/src/lib/virtualized/project/analyzeRegularCommit.js.map +1 -1
- package/background/src/lib/virtualized/project/constructMockCode.js +799 -121
- package/background/src/lib/virtualized/project/constructMockCode.js.map +1 -1
- package/background/src/lib/virtualized/project/controller/startController.js +11 -1
- package/background/src/lib/virtualized/project/controller/startController.js.map +1 -1
- package/background/src/lib/virtualized/project/executeLibraryFunctionDirect.js +6 -3
- package/background/src/lib/virtualized/project/executeLibraryFunctionDirect.js.map +1 -1
- package/background/src/lib/virtualized/project/mocks/analyzeFileMock.js +7 -7
- package/background/src/lib/virtualized/project/mocks/analyzeFileMock.js.map +1 -1
- package/background/src/lib/virtualized/project/orchestrateCapture/KyselyAnalysisLoader.js +3 -2
- package/background/src/lib/virtualized/project/orchestrateCapture/KyselyAnalysisLoader.js.map +1 -1
- package/background/src/lib/virtualized/project/orchestrateCapture/SequentialCaptureTaskRunner.js +42 -28
- package/background/src/lib/virtualized/project/orchestrateCapture/SequentialCaptureTaskRunner.js.map +1 -1
- package/background/src/lib/virtualized/project/orchestrateCapture.js +7 -4
- package/background/src/lib/virtualized/project/orchestrateCapture.js.map +1 -1
- package/background/src/lib/virtualized/project/reconcileMockDataKeys.js +87 -2
- package/background/src/lib/virtualized/project/reconcileMockDataKeys.js.map +1 -1
- package/background/src/lib/virtualized/project/runAnalysis.js +6 -0
- package/background/src/lib/virtualized/project/runAnalysis.js.map +1 -1
- package/background/src/lib/virtualized/project/serverOnlyModules.js +106 -3
- package/background/src/lib/virtualized/project/serverOnlyModules.js.map +1 -1
- package/background/src/lib/virtualized/project/start.js +21 -4
- package/background/src/lib/virtualized/project/start.js.map +1 -1
- package/background/src/lib/virtualized/project/startScenarioCapture.js +56 -30
- package/background/src/lib/virtualized/project/startScenarioCapture.js.map +1 -1
- package/background/src/lib/virtualized/project/writeMockDataTsx.js +110 -48
- package/background/src/lib/virtualized/project/writeMockDataTsx.js.map +1 -1
- package/background/src/lib/virtualized/project/writeScenarioClientWrapper.js +15 -0
- package/background/src/lib/virtualized/project/writeScenarioClientWrapper.js.map +1 -0
- package/background/src/lib/virtualized/project/writeScenarioComponents.js +211 -75
- package/background/src/lib/virtualized/project/writeScenarioComponents.js.map +1 -1
- package/background/src/lib/virtualized/project/writeScenarioFiles.js +19 -0
- package/background/src/lib/virtualized/project/writeScenarioFiles.js.map +1 -1
- package/background/src/lib/virtualized/project/writeSimpleRoot.js +13 -13
- package/background/src/lib/virtualized/project/writeSimpleRoot.js.map +1 -1
- package/codeyam-cli/src/cli.js +5 -1
- package/codeyam-cli/src/cli.js.map +1 -1
- package/codeyam-cli/src/commands/analyze.js +1 -1
- package/codeyam-cli/src/commands/analyze.js.map +1 -1
- package/codeyam-cli/src/commands/baseline.js +174 -0
- package/codeyam-cli/src/commands/baseline.js.map +1 -0
- package/codeyam-cli/src/commands/debug.js +28 -18
- package/codeyam-cli/src/commands/debug.js.map +1 -1
- package/codeyam-cli/src/commands/default.js +0 -15
- package/codeyam-cli/src/commands/default.js.map +1 -1
- package/codeyam-cli/src/commands/recapture.js +44 -23
- package/codeyam-cli/src/commands/recapture.js.map +1 -1
- package/codeyam-cli/src/commands/report.js +72 -24
- package/codeyam-cli/src/commands/report.js.map +1 -1
- package/codeyam-cli/src/commands/start.js +8 -12
- package/codeyam-cli/src/commands/start.js.map +1 -1
- package/codeyam-cli/src/commands/status.js +23 -1
- package/codeyam-cli/src/commands/status.js.map +1 -1
- package/codeyam-cli/src/commands/test-startup.js +1 -1
- package/codeyam-cli/src/commands/test-startup.js.map +1 -1
- package/codeyam-cli/src/commands/wipe.js +108 -0
- package/codeyam-cli/src/commands/wipe.js.map +1 -0
- package/codeyam-cli/src/utils/__tests__/serverVersionStaleness.test.js +81 -0
- package/codeyam-cli/src/utils/__tests__/serverVersionStaleness.test.js.map +1 -0
- package/codeyam-cli/src/utils/__tests__/setupClaudeCodeSettings.test.js +27 -27
- package/codeyam-cli/src/utils/analysisRunner.js +8 -13
- package/codeyam-cli/src/utils/analysisRunner.js.map +1 -1
- package/codeyam-cli/src/utils/backgroundServer.js +12 -2
- package/codeyam-cli/src/utils/backgroundServer.js.map +1 -1
- package/codeyam-cli/src/utils/database.js +91 -5
- package/codeyam-cli/src/utils/database.js.map +1 -1
- package/codeyam-cli/src/utils/generateReport.js +253 -106
- package/codeyam-cli/src/utils/generateReport.js.map +1 -1
- package/codeyam-cli/src/utils/git.js +79 -0
- package/codeyam-cli/src/utils/git.js.map +1 -0
- package/codeyam-cli/src/utils/install-skills.js +11 -11
- 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 +239 -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/utils/serverState.js.map +1 -1
- package/codeyam-cli/src/utils/setupClaudeCodeSettings.js +5 -5
- package/codeyam-cli/src/utils/versionInfo.js +25 -19
- package/codeyam-cli/src/utils/versionInfo.js.map +1 -1
- package/codeyam-cli/src/utils/wipe.js +128 -0
- package/codeyam-cli/src/utils/wipe.js.map +1 -0
- package/codeyam-cli/src/webserver/app/lib/database.js +96 -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 +2 -5
- package/codeyam-cli/src/webserver/backgroundServer.js.map +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/EntityItem-vauWK972.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{EntityTypeBadge-DKdsUF7Y.js → EntityTypeBadge-COi5OvsN.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/EntityTypeIcon-BwdQv49w.js +41 -0
- package/codeyam-cli/src/webserver/build/client/assets/InlineSpinner-CEleMv_j.js +34 -0
- package/codeyam-cli/src/webserver/build/client/assets/InteractivePreview-D68KarMg.js +25 -0
- package/codeyam-cli/src/webserver/build/client/assets/LibraryFunctionPreview-L75Wvqgw.js +3 -0
- package/codeyam-cli/src/webserver/build/client/assets/LoadingDots-C53WM8qn.js +6 -0
- package/codeyam-cli/src/webserver/build/client/assets/LogViewer-CrNkmy4i.js +3 -0
- package/codeyam-cli/src/webserver/build/client/assets/ReportIssueModal-DzJRkCkr.js +11 -0
- package/codeyam-cli/src/webserver/build/client/assets/SafeScreenshot-CQifa1n-.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/ScenarioViewer-CyaBFX7l.js +20 -0
- package/codeyam-cli/src/webserver/build/client/assets/{TruncatedFilePath-CWjSsLqY.js → TruncatedFilePath-D36O1rzU.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/_index-Be83mo_j.js +11 -0
- package/codeyam-cli/src/webserver/build/client/assets/activity.(_tab)-BN6wu6Y-.js +37 -0
- package/codeyam-cli/src/webserver/build/client/assets/chevron-down-DgTPh8H-.js +6 -0
- package/codeyam-cli/src/webserver/build/client/assets/chunk-EPOLDU6W-DdQKK6on.js +51 -0
- package/codeyam-cli/src/webserver/build/client/assets/circle-check-Dmr2bb1R.js +6 -0
- package/codeyam-cli/src/webserver/build/client/assets/createLucideIcon-Do4ZLUYa.js +21 -0
- package/codeyam-cli/src/webserver/build/client/assets/{cy-logo-cli-C1gnJVOL.svg → cy-logo-cli-CCKUIm0S.svg} +2 -2
- package/codeyam-cli/src/webserver/build/client/assets/cy-logo-cli-DcX-ZS3p.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/dev.empty-Bn6aCAy_.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha._-CbdFyxZh.js +23 -0
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha.scenarios._scenarioId.fullscreen-B4iCfs5M.js +6 -0
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.create-scenario-wDWZZO1W.js +6 -0
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.edit._scenarioId-BMbl7MeQ.js +5 -0
- package/codeyam-cli/src/webserver/build/client/assets/entry.client-5wRKRIH9.js +29 -0
- package/codeyam-cli/src/webserver/build/client/assets/executionFlowCoverage-BWhdfn70.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/fileTableUtils-DD3SDH7t.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/files-DKyMFI90.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/git-zXjT7J0G.js +15 -0
- package/codeyam-cli/src/webserver/build/client/assets/globals-DTTQ3gY7.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-DLbXwndH.js +9 -0
- package/codeyam-cli/src/webserver/build/client/assets/index-gPZ-lad1.js +3 -0
- package/codeyam-cli/src/webserver/build/client/assets/loader-circle-BsPXJ81F.js +6 -0
- package/codeyam-cli/src/webserver/build/client/assets/manifest-22590fcf.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-BsAarjAM.js +57 -0
- package/codeyam-cli/src/webserver/build/client/assets/scenarioStatus-B_8jpV3e.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/search-P2FKIUql.js +6 -0
- package/codeyam-cli/src/webserver/build/client/assets/settings-B2eDuBj8.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/simulations-L18M6-kN.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/triangle-alert-BDz7kbVA.js +6 -0
- package/codeyam-cli/src/webserver/build/client/assets/useCustomSizes-29dDmbH8.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{useLastLogLine-CmrTPlIB.js → useLastLogLine-BUm0UVJm.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/useReportContext-CkIOKTrZ.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{useToast-C1ig_BmP.js → useToast-KKw5kTn-.js} +1 -1
- package/codeyam-cli/src/webserver/build/server/assets/index-BND5I5fv.js +1 -0
- package/codeyam-cli/src/webserver/build/server/assets/server-build-CFXnd7MG.js +228 -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/src/webserver/server.js +35 -25
- package/codeyam-cli/src/webserver/server.js.map +1 -1
- package/codeyam-cli/templates/{codeyam-debug-skill.md → codeyam:debug.md} +1 -1
- package/codeyam-cli/templates/codeyam:diagnose.md +625 -0
- package/codeyam-cli/templates/{codeyam-setup-skill.md → codeyam:setup.md} +139 -4
- package/codeyam-cli/templates/{codeyam-sim-skill.md → codeyam:sim.md} +1 -1
- package/codeyam-cli/templates/{codeyam-test-skill.md → codeyam:test.md} +1 -1
- package/codeyam-cli/templates/{codeyam-verify-skill.md → codeyam:verify.md} +1 -1
- package/package.json +8 -8
- package/packages/ai/index.js +2 -4
- package/packages/ai/index.js.map +1 -1
- package/packages/ai/src/lib/analyzeScope.js +107 -0
- package/packages/ai/src/lib/analyzeScope.js.map +1 -1
- package/packages/ai/src/lib/astScopes/astScopeAnalyzer.js +76 -1
- package/packages/ai/src/lib/astScopes/astScopeAnalyzer.js.map +1 -1
- package/packages/ai/src/lib/astScopes/conditionalEffectsExtractor.js +435 -0
- package/packages/ai/src/lib/astScopes/conditionalEffectsExtractor.js.map +1 -0
- package/packages/ai/src/lib/astScopes/methodSemantics.js +29 -0
- package/packages/ai/src/lib/astScopes/methodSemantics.js.map +1 -1
- package/packages/ai/src/lib/astScopes/patterns/ifStatementHandler.js +8 -0
- package/packages/ai/src/lib/astScopes/patterns/ifStatementHandler.js.map +1 -1
- package/packages/ai/src/lib/astScopes/patterns/switchStatementHandler.js +23 -0
- package/packages/ai/src/lib/astScopes/patterns/switchStatementHandler.js.map +1 -1
- package/packages/ai/src/lib/astScopes/patterns/variableDeclarationHandler.js +239 -1
- package/packages/ai/src/lib/astScopes/patterns/variableDeclarationHandler.js.map +1 -1
- package/packages/ai/src/lib/astScopes/processExpression.js +728 -87
- package/packages/ai/src/lib/astScopes/processExpression.js.map +1 -1
- package/packages/ai/src/lib/checkAllAttributes.js +24 -9
- package/packages/ai/src/lib/checkAllAttributes.js.map +1 -1
- package/packages/ai/src/lib/completionCall.js +17 -1
- package/packages/ai/src/lib/completionCall.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js +1126 -82
- 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 +482 -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 +35 -2
- 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 +34 -3
- package/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.js.map +1 -1
- package/packages/ai/src/lib/deepEqual.js +32 -0
- package/packages/ai/src/lib/deepEqual.js.map +1 -0
- package/packages/ai/src/lib/generateChangesEntityScenarioData.js +62 -5
- package/packages/ai/src/lib/generateChangesEntityScenarioData.js.map +1 -1
- package/packages/ai/src/lib/generateChangesEntityScenarios.js +81 -90
- package/packages/ai/src/lib/generateChangesEntityScenarios.js.map +1 -1
- package/packages/ai/src/lib/generateEntityDataStructure.js +5 -0
- package/packages/ai/src/lib/generateEntityDataStructure.js.map +1 -1
- package/packages/ai/src/lib/generateEntityScenarioData.js +398 -81
- package/packages/ai/src/lib/generateEntityScenarioData.js.map +1 -1
- package/packages/ai/src/lib/generateEntityScenarios.js +168 -82
- package/packages/ai/src/lib/generateEntityScenarios.js.map +1 -1
- package/packages/ai/src/lib/generateExecutionFlows.js +123 -0
- package/packages/ai/src/lib/generateExecutionFlows.js.map +1 -0
- package/packages/ai/src/lib/generateExecutionFlowsFromConditionalEffects.js +380 -0
- package/packages/ai/src/lib/generateExecutionFlowsFromConditionalEffects.js.map +1 -0
- package/packages/ai/src/lib/generateExecutionFlowsFromConditionals.js +742 -0
- package/packages/ai/src/lib/generateExecutionFlowsFromConditionals.js.map +1 -0
- 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/isolateScopes.js +231 -4
- package/packages/ai/src/lib/isolateScopes.js.map +1 -1
- package/packages/ai/src/lib/mergeStatements.js +26 -3
- package/packages/ai/src/lib/mergeStatements.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/generateChangesEntityScenarioDataGenerator.js +1 -1
- package/packages/ai/src/lib/promptGenerators/generateChangesEntityScenarioDataGenerator.js.map +1 -1
- package/packages/ai/src/lib/promptGenerators/generateChangesEntityScenariosGenerator.js +21 -64
- package/packages/ai/src/lib/promptGenerators/generateChangesEntityScenariosGenerator.js.map +1 -1
- package/packages/ai/src/lib/promptGenerators/generateEntityScenarioDataGenerator.js +58 -4
- package/packages/ai/src/lib/promptGenerators/generateEntityScenarioDataGenerator.js.map +1 -1
- package/packages/ai/src/lib/promptGenerators/generateEntityScenariosGenerator.js +10 -34
- package/packages/ai/src/lib/promptGenerators/generateEntityScenariosGenerator.js.map +1 -1
- package/packages/ai/src/lib/promptGenerators/generateMissingKeysPrompt.js +45 -0
- package/packages/ai/src/lib/promptGenerators/generateMissingKeysPrompt.js.map +1 -0
- 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/resolvePathToControllable.js +563 -0
- package/packages/ai/src/lib/resolvePathToControllable.js.map +1 -0
- package/packages/ai/src/lib/splitOutsideParentheses.js +3 -1
- package/packages/ai/src/lib/splitOutsideParentheses.js.map +1 -1
- package/packages/ai/src/lib/worker/SerializableDataStructure.js +22 -0
- 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/FileAnalyzer.js +15 -0
- package/packages/analyze/src/lib/FileAnalyzer.js.map +1 -1
- package/packages/analyze/src/lib/asts/nodes/index.js +1 -0
- package/packages/analyze/src/lib/asts/nodes/index.js.map +1 -1
- package/packages/analyze/src/lib/asts/nodes/isAsyncFunction.js +52 -0
- package/packages/analyze/src/lib/asts/nodes/isAsyncFunction.js.map +1 -0
- package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js +214 -50
- package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js.map +1 -1
- package/packages/analyze/src/lib/files/analyze/analyzeEntities.js +10 -0
- package/packages/analyze/src/lib/files/analyze/analyzeEntities.js.map +1 -1
- package/packages/analyze/src/lib/files/analyze/findOrCreateEntity.js +2 -0
- package/packages/analyze/src/lib/files/analyze/findOrCreateEntity.js.map +1 -1
- package/packages/analyze/src/lib/files/analyzeChange.js +21 -11
- package/packages/analyze/src/lib/files/analyzeChange.js.map +1 -1
- package/packages/analyze/src/lib/files/analyzeEntity.js +9 -8
- package/packages/analyze/src/lib/files/analyzeEntity.js.map +1 -1
- package/packages/analyze/src/lib/files/analyzeInitial.js +9 -10
- package/packages/analyze/src/lib/files/analyzeInitial.js.map +1 -1
- package/packages/analyze/src/lib/files/enums/steps.js +1 -1
- package/packages/analyze/src/lib/files/enums/steps.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/enrichArrayTypesFromChildSignatures.js +159 -0
- package/packages/analyze/src/lib/files/scenarios/enrichArrayTypesFromChildSignatures.js.map +1 -0
- package/packages/analyze/src/lib/files/scenarios/enrichUnknownTypesFromSourceEquivalencies.js +85 -0
- package/packages/analyze/src/lib/files/scenarios/enrichUnknownTypesFromSourceEquivalencies.js.map +1 -0
- package/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.js +458 -48
- 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/generateChangesScenarios.js +29 -34
- package/packages/analyze/src/lib/files/scenarios/generateChangesScenarios.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/generateDataStructure.js +235 -81
- package/packages/analyze/src/lib/files/scenarios/generateDataStructure.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/generateExecutionFlows.js +96 -0
- package/packages/analyze/src/lib/files/scenarios/generateExecutionFlows.js.map +1 -0
- package/packages/analyze/src/lib/files/scenarios/generateScenarioData.js +56 -69
- package/packages/analyze/src/lib/files/scenarios/generateScenarioData.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/generateScenarios.js +4 -8
- package/packages/analyze/src/lib/files/scenarios/generateScenarios.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js +307 -89
- package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js.map +1 -1
- package/packages/aws/src/lib/ecs/ecsDefineContainer.js +2 -2
- package/packages/aws/src/lib/ecs/ecsDefineContainer.js.map +1 -1
- package/packages/aws/src/lib/ecs/ecsTaskFactory.js +17 -61
- package/packages/aws/src/lib/ecs/ecsTaskFactory.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 +7 -4
- package/packages/database/src/lib/loadReadyToBeCapturedAnalyses.js.map +1 -1
- package/packages/generate/index.js +3 -0
- package/packages/generate/index.js.map +1 -1
- package/packages/generate/src/lib/componentScenarioPage/componentScenarioPageNext.js +16 -1
- package/packages/generate/src/lib/componentScenarioPage/componentScenarioPageNext.js.map +1 -1
- package/packages/generate/src/lib/componentScenarioPage/generateScenarioClientWrapper.js +189 -0
- package/packages/generate/src/lib/componentScenarioPage/generateScenarioClientWrapper.js.map +1 -0
- package/packages/generate/src/lib/componentScenarioPage/generateScenarioServerComponent.js +53 -0
- package/packages/generate/src/lib/componentScenarioPage/generateScenarioServerComponent.js.map +1 -0
- 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/scenarioComponentForServer.js +89 -0
- package/packages/generate/src/lib/scenarioComponentForServer.js.map +1 -0
- package/packages/github/src/lib/loadOrCreateCommit.js +10 -0
- package/packages/github/src/lib/loadOrCreateCommit.js.map +1 -1
- package/packages/github/src/lib/syncPrimaryBranch.js +3 -0
- package/packages/github/src/lib/syncPrimaryBranch.js.map +1 -1
- package/packages/process/index.js +3 -0
- package/packages/process/index.js.map +1 -0
- package/packages/process/src/GlobalProcessManager.js.map +1 -0
- package/{background/src/lib/process → packages/process/src}/ProcessManager.js +1 -1
- package/packages/process/src/ProcessManager.js.map +1 -0
- package/packages/process/src/index.js.map +1 -0
- package/packages/process/src/managedExecAsync.js.map +1 -0
- package/packages/types/index.js.map +1 -1
- package/scripts/finalize-analyzer.cjs +3 -1
- package/analyzer-template/packages/ai/src/lib/findMatchingAttribute.ts +0 -102
- package/analyzer-template/packages/ai/src/lib/gatherRelevantDependentKeyAttributes.ts +0 -197
- package/analyzer-template/packages/ai/src/lib/generateChangesEntityKeyAttributes.ts +0 -271
- package/analyzer-template/packages/ai/src/lib/generateEntityKeyAttributes.ts +0 -294
- package/analyzer-template/packages/ai/src/lib/promptGenerators/generateEntityKeyAttributesGenerator.ts +0 -67
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateKeyAttributes.ts +0 -115
- package/analyzer-template/process/INTEGRATION_COMPLETE.md +0 -333
- package/analyzer-template/process/INTEGRATION_EXAMPLE.md +0 -525
- package/analyzer-template/process/README.md +0 -507
- package/background/src/lib/process/GlobalProcessManager.js.map +0 -1
- package/background/src/lib/process/ProcessManager.js.map +0 -1
- package/background/src/lib/process/index.js.map +0 -1
- package/background/src/lib/process/managedExecAsync.js.map +0 -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-D0VW1-W7.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/EntityTypeIcon-BAk4S4pI.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/InteractivePreview-Y756iZxZ.js +0 -25
- package/codeyam-cli/src/webserver/build/client/assets/LibraryFunctionPreview-zzrrjW1p.js +0 -3
- package/codeyam-cli/src/webserver/build/client/assets/LogViewer-QMn7bJg6.js +0 -3
- package/codeyam-cli/src/webserver/build/client/assets/ReportIssueModal-DmP5mRxX.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/SafeScreenshot-BXwvsbLw.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/ScenarioViewer-DAmUX_1y.js +0 -5
- package/codeyam-cli/src/webserver/build/client/assets/_index-Df-nk4J5.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/activity.(_tab)-_ZUyFdie.js +0 -7
- package/codeyam-cli/src/webserver/build/client/assets/chevron-down-Eoh0PhcW.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/chunk-WWGJGFF6-CZgPLy5i.js +0 -26
- package/codeyam-cli/src/webserver/build/client/assets/circle-check-DI-p9ZLZ.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/createLucideIcon-DvyV2x6y.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/dev.empty-DURu2qlF.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha._-DDobn9Xh.js +0 -16
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.create-scenario-CGdWnLD_.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.edit._scenarioId-DgMmzrKs.js +0 -5
- package/codeyam-cli/src/webserver/build/client/assets/entry.client-DEVXuhkn.js +0 -13
- package/codeyam-cli/src/webserver/build/client/assets/fileTableUtils-WPRQyc68.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/files-B9u3lJer.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/git-YGnKIuHU.js +0 -11
- package/codeyam-cli/src/webserver/build/client/assets/globals-28lrWTTo.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-CJ0uPJjV.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/index-CfqeA2XG.js +0 -3
- package/codeyam-cli/src/webserver/build/client/assets/loader-circle-DIjSvh6B.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/manifest-8125c15c.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/preload-helper-BXl3LOEh.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/root-C-g286WP.js +0 -16
- package/codeyam-cli/src/webserver/build/client/assets/search-xBKWfOxd.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/settings-DVY_wGOx.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/simulations-Be1pJo5A.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/triangle-alert-CR-FkSvx.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/useReportContext-DABetnSj.js +0 -1
- package/codeyam-cli/src/webserver/build/server/assets/index-DcR7DH9q.js +0 -1
- package/codeyam-cli/src/webserver/build/server/assets/server-build-BDBrfp7e.js +0 -175
- package/codeyam-cli/templates/debug-codeyam.md +0 -527
- package/packages/ai/src/lib/findMatchingAttribute.js +0 -77
- package/packages/ai/src/lib/findMatchingAttribute.js.map +0 -1
- package/packages/ai/src/lib/gatherRelevantDependentKeyAttributes.js +0 -136
- package/packages/ai/src/lib/gatherRelevantDependentKeyAttributes.js.map +0 -1
- package/packages/ai/src/lib/generateChangesEntityKeyAttributes.js +0 -220
- package/packages/ai/src/lib/generateChangesEntityKeyAttributes.js.map +0 -1
- package/packages/ai/src/lib/generateEntityKeyAttributes.js +0 -241
- package/packages/ai/src/lib/generateEntityKeyAttributes.js.map +0 -1
- package/packages/ai/src/lib/isFrontend.js +0 -5
- package/packages/ai/src/lib/isFrontend.js.map +0 -1
- package/packages/ai/src/lib/promptGenerators/generateEntityKeyAttributesGenerator.js +0 -40
- package/packages/ai/src/lib/promptGenerators/generateEntityKeyAttributesGenerator.js.map +0 -1
- package/packages/analyze/src/lib/files/scenarios/generateKeyAttributes.js +0 -72
- package/packages/analyze/src/lib/files/scenarios/generateKeyAttributes.js.map +0 -1
- /package/analyzer-template/{process → packages/process/src}/GlobalProcessManager.ts +0 -0
- /package/analyzer-template/{process → packages/process/src}/ProcessManager.ts +0 -0
- /package/analyzer-template/{process → packages/process/src}/index.ts +0 -0
- /package/analyzer-template/{process → packages/process/src}/managedExecAsync.ts +0 -0
- /package/{background/src/lib/process → packages/process/src}/GlobalProcessManager.js +0 -0
- /package/{background/src/lib/process → packages/process/src}/index.js +0 -0
- /package/{background/src/lib/process → packages/process/src}/managedExecAsync.js +0 -0
|
@@ -1,9 +1,187 @@
|
|
|
1
1
|
import ts from 'typescript';
|
|
2
|
+
import * as crypto from 'crypto';
|
|
2
3
|
import { StructuredPath } from "./paths.js";
|
|
3
4
|
import { nodeToSource } from "./nodeToSource.js";
|
|
4
5
|
import { methodRegistry, ArrayPushSemantics } from "./methodSemantics.js";
|
|
5
6
|
import { isArithmeticOperator, isAssignmentOperator, isBitwiseCompoundOperator, isComparisonOperator, isDefinedType, isNumericCompoundOperator, leftOrRightType, unwrapExpression, } from "./sharedPatterns.js";
|
|
6
7
|
import { processBindingPattern } from "./processBindings.js";
|
|
8
|
+
import { extractConditionalEffectsFromTernary, findUseStateSetters, } from "./conditionalEffectsExtractor.js";
|
|
9
|
+
/**
|
|
10
|
+
* Extracts the component name from a JSX element.
|
|
11
|
+
* Returns null for intrinsic elements (div, span, etc.) since we only care about
|
|
12
|
+
* custom components for gating condition tracking.
|
|
13
|
+
*
|
|
14
|
+
* Examples:
|
|
15
|
+
* - <ChildViewer /> → "ChildViewer"
|
|
16
|
+
* - <ScenarioViewer scenario={...} /> → "ScenarioViewer"
|
|
17
|
+
* - <div> → null (intrinsic element)
|
|
18
|
+
*/
|
|
19
|
+
function getComponentNameFromJsx(node) {
|
|
20
|
+
let tagName;
|
|
21
|
+
if (ts.isJsxElement(node)) {
|
|
22
|
+
tagName = node.openingElement.tagName;
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
tagName = node.tagName;
|
|
26
|
+
}
|
|
27
|
+
// Get the text of the tag name
|
|
28
|
+
const name = tagName.getText();
|
|
29
|
+
// Check if it's a custom component (starts with uppercase) vs intrinsic element
|
|
30
|
+
// Custom components start with uppercase: <MyComponent />
|
|
31
|
+
// Intrinsic elements start with lowercase: <div />
|
|
32
|
+
if (name &&
|
|
33
|
+
name[0] === name[0].toUpperCase() &&
|
|
34
|
+
name[0] !== name[0].toLowerCase()) {
|
|
35
|
+
return name;
|
|
36
|
+
}
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Extracts condition paths from a logical AND chain expression.
|
|
41
|
+
* Used for creating gating conditions for child components.
|
|
42
|
+
*
|
|
43
|
+
* Example: `hasData && isReady && <Component />` returns ['hasData', 'isReady']
|
|
44
|
+
*/
|
|
45
|
+
function extractConditionPathsFromAndChain(expr, sourceFile) {
|
|
46
|
+
const paths = [];
|
|
47
|
+
const unwrapped = unwrapExpression(expr);
|
|
48
|
+
if (ts.isBinaryExpression(unwrapped) &&
|
|
49
|
+
unwrapped.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken) {
|
|
50
|
+
// Recursively get conditions from left side
|
|
51
|
+
paths.push(...extractConditionPathsFromAndChain(unwrapped.left, sourceFile));
|
|
52
|
+
// Process right side if it's not JSX (JSX is the consequence, not a condition)
|
|
53
|
+
const rightUnwrapped = unwrapExpression(unwrapped.right);
|
|
54
|
+
if (!ts.isJsxElement(rightUnwrapped) &&
|
|
55
|
+
!ts.isJsxSelfClosingElement(rightUnwrapped) &&
|
|
56
|
+
!ts.isJsxFragment(rightUnwrapped)) {
|
|
57
|
+
paths.push(...extractConditionPathsFromAndChain(unwrapped.right, sourceFile));
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
// Base case: extract path from this expression
|
|
62
|
+
const path = StructuredPath.fromNode(unwrapped, sourceFile);
|
|
63
|
+
if (path) {
|
|
64
|
+
paths.push(path.toString());
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return paths;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Finds the rightmost JSX element in an && chain.
|
|
71
|
+
* Example: `a && b && <Component />` returns <Component />
|
|
72
|
+
*/
|
|
73
|
+
function findJsxInAndChain(expr) {
|
|
74
|
+
const unwrapped = unwrapExpression(expr);
|
|
75
|
+
if (ts.isJsxElement(unwrapped) || ts.isJsxSelfClosingElement(unwrapped)) {
|
|
76
|
+
return unwrapped;
|
|
77
|
+
}
|
|
78
|
+
if (ts.isBinaryExpression(unwrapped) &&
|
|
79
|
+
unwrapped.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken) {
|
|
80
|
+
// Check right side first (most common case: condition && <Jsx />)
|
|
81
|
+
const rightResult = findJsxInAndChain(unwrapped.right);
|
|
82
|
+
if (rightResult)
|
|
83
|
+
return rightResult;
|
|
84
|
+
// Also check left side for rare cases
|
|
85
|
+
return findJsxInAndChain(unwrapped.left);
|
|
86
|
+
}
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Fix 32: Finds a JSX fragment in an && chain.
|
|
91
|
+
* Example: `activeTab && <><ChildA /><ChildB /></>` returns the fragment
|
|
92
|
+
* This is needed to propagate parent conditions through fragments.
|
|
93
|
+
*/
|
|
94
|
+
function findJsxFragmentInAndChain(expr) {
|
|
95
|
+
const unwrapped = unwrapExpression(expr);
|
|
96
|
+
if (ts.isJsxFragment(unwrapped)) {
|
|
97
|
+
return unwrapped;
|
|
98
|
+
}
|
|
99
|
+
if (ts.isBinaryExpression(unwrapped) &&
|
|
100
|
+
unwrapped.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken) {
|
|
101
|
+
// Check right side first (most common case: condition && <></>)
|
|
102
|
+
const rightResult = findJsxFragmentInAndChain(unwrapped.right);
|
|
103
|
+
if (rightResult)
|
|
104
|
+
return rightResult;
|
|
105
|
+
// Also check left side for rare cases
|
|
106
|
+
return findJsxFragmentInAndChain(unwrapped.left);
|
|
107
|
+
}
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Detects if a property access looks like an environment variable store access.
|
|
112
|
+
* Matches patterns like `env.DATABASE_URL`, `env.IS_FORMBRICKS_CLOUD`, etc.
|
|
113
|
+
* where the object is named "env" and the property looks like an env var name.
|
|
114
|
+
*/
|
|
115
|
+
function isEnvStoreAccess(fullText) {
|
|
116
|
+
// Match: env.SOME_VAR or env.someVar (but object must be exactly "env")
|
|
117
|
+
// This catches patterns from @t3-oss/env-nextjs and similar packages
|
|
118
|
+
const envStorePattern = /^env\.[A-Z_][A-Z0-9_]*$/;
|
|
119
|
+
return envStorePattern.test(fullText);
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Converts a call expression argument to a StructuredPath.
|
|
123
|
+
*
|
|
124
|
+
* IMPORTANT: We always use the original source text for callbacks, never cyScope names.
|
|
125
|
+
* cyScope names are internal identifiers for child scopes and should NEVER appear
|
|
126
|
+
* in schema paths or call signatures. Using cyScope names causes data merge conflicts
|
|
127
|
+
* because the same callback gets different identifiers in different contexts.
|
|
128
|
+
*/
|
|
129
|
+
function getArgPathForCallSignature(arg, context) {
|
|
130
|
+
// Always use the standard path conversion - never replace with cyScope names
|
|
131
|
+
return (StructuredPath.fromNode(arg, context.sourceFile) ||
|
|
132
|
+
nodeToSource(arg, context.sourceFile));
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Builds a StructuredPath for a call expression using the original source text.
|
|
136
|
+
*
|
|
137
|
+
* IMPORTANT: This function ensures consistent call signatures by always using
|
|
138
|
+
* the original callback text, never cyScope names. This prevents schema path
|
|
139
|
+
* conflicts where the same call would have different paths.
|
|
140
|
+
*/
|
|
141
|
+
function buildCallPathFromSource(node, context) {
|
|
142
|
+
const expression = node.expression;
|
|
143
|
+
// Convert arguments using original source text
|
|
144
|
+
const argPaths = node.arguments.map((arg) => getArgPathForCallSignature(arg, context));
|
|
145
|
+
// Handle type arguments if present
|
|
146
|
+
let typeArgs = undefined;
|
|
147
|
+
if (node.typeArguments && node.typeArguments.length > 0) {
|
|
148
|
+
typeArgs = node.typeArguments.map((typeArg) => typeArg.getText(context.sourceFile));
|
|
149
|
+
}
|
|
150
|
+
if (ts.isIdentifier(expression)) {
|
|
151
|
+
// Simple function call: func(arg1, arg2)
|
|
152
|
+
return StructuredPath.fromFunction(expression.text, argPaths, typeArgs);
|
|
153
|
+
}
|
|
154
|
+
else if (ts.isPropertyAccessExpression(expression)) {
|
|
155
|
+
// Method call: obj.method(arg1, arg2)
|
|
156
|
+
const objPath = StructuredPath.fromNode(expression.expression, context.sourceFile);
|
|
157
|
+
if (!objPath)
|
|
158
|
+
return null;
|
|
159
|
+
return objPath
|
|
160
|
+
.withProperty(expression.name.text)
|
|
161
|
+
.withFunctionCall(argPaths, typeArgs);
|
|
162
|
+
}
|
|
163
|
+
else if (ts.isCallExpression(expression)) {
|
|
164
|
+
// Chained call: func(arg1)(arg2)
|
|
165
|
+
const funcPath = buildCallPathFromSource(expression, context);
|
|
166
|
+
if (!funcPath)
|
|
167
|
+
return null;
|
|
168
|
+
return funcPath.withFunctionCall(argPaths, typeArgs);
|
|
169
|
+
}
|
|
170
|
+
else if (ts.isElementAccessExpression(expression)) {
|
|
171
|
+
// Element access call: obj[key](args)
|
|
172
|
+
const basePath = StructuredPath.fromNode(expression, context.sourceFile);
|
|
173
|
+
if (!basePath)
|
|
174
|
+
return null;
|
|
175
|
+
return basePath.withFunctionCall(argPaths, typeArgs);
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
// Complex call expression
|
|
179
|
+
const basePath = StructuredPath.fromNode(expression, context.sourceFile);
|
|
180
|
+
if (!basePath)
|
|
181
|
+
return null;
|
|
182
|
+
return basePath.withFunctionCall(argPaths, typeArgs);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
7
185
|
/**
|
|
8
186
|
* Checks if an expression is likely an array type.
|
|
9
187
|
* Uses TypeScript's type checker when available, falls back to heuristics.
|
|
@@ -81,102 +259,508 @@ export function markConditionVariablesAsNullable(condition, context) {
|
|
|
81
259
|
}
|
|
82
260
|
}
|
|
83
261
|
/**
|
|
84
|
-
*
|
|
85
|
-
* This function identifies which attributes are used in conditionals and how they're used.
|
|
86
|
-
*
|
|
87
|
-
* @param condition The condition expression to analyze
|
|
88
|
-
* @param context The analysis context
|
|
89
|
-
* @param location Where this condition appears (if, ternary, logical-and, switch)
|
|
262
|
+
* Helper to extract source location from an AST node
|
|
90
263
|
*/
|
|
91
|
-
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
264
|
+
function getSourceLocation(node, sourceFile) {
|
|
265
|
+
const start = node.getStart(sourceFile);
|
|
266
|
+
const { line, character } = sourceFile.getLineAndCharacterOfPosition(start);
|
|
267
|
+
const codeSnippet = node.getText(sourceFile);
|
|
268
|
+
return {
|
|
269
|
+
lineNumber: line + 1, // Convert to 1-based
|
|
270
|
+
column: character,
|
|
271
|
+
codeSnippet: codeSnippet.length > 100
|
|
272
|
+
? codeSnippet.slice(0, 100) + '...'
|
|
273
|
+
: codeSnippet,
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Counts the number of conditions in an && chain (excluding JSX consequence)
|
|
278
|
+
*/
|
|
279
|
+
function countConditionsInAndChain(expr) {
|
|
280
|
+
const unwrapped = unwrapExpression(expr);
|
|
95
281
|
if (ts.isBinaryExpression(unwrapped) &&
|
|
96
282
|
unwrapped.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken) {
|
|
97
|
-
|
|
98
|
-
extractConditionalUsage(unwrapped.left, context, location);
|
|
99
|
-
// Process right side if it's not JSX (JSX is the consequence, not the condition)
|
|
283
|
+
const leftCount = countConditionsInAndChain(unwrapped.left);
|
|
100
284
|
const rightUnwrapped = unwrapExpression(unwrapped.right);
|
|
101
285
|
const isJsxConsequence = ts.isJsxElement(rightUnwrapped) ||
|
|
102
286
|
ts.isJsxSelfClosingElement(rightUnwrapped) ||
|
|
103
287
|
ts.isJsxFragment(rightUnwrapped);
|
|
104
|
-
if (
|
|
105
|
-
|
|
288
|
+
if (isJsxConsequence) {
|
|
289
|
+
return leftCount;
|
|
106
290
|
}
|
|
107
|
-
return;
|
|
291
|
+
return leftCount + countConditionsInAndChain(unwrapped.right);
|
|
108
292
|
}
|
|
109
|
-
//
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
293
|
+
// Single condition (not an && chain)
|
|
294
|
+
return 1;
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Extracts conditionals from JSX elements by recursively traversing children.
|
|
298
|
+
*
|
|
299
|
+
* This is CRITICAL for extracting compound conditionals from JSX expressions
|
|
300
|
+
* like `{hasNewerVersion && !isActive && <Banner />}`.
|
|
301
|
+
*
|
|
302
|
+
* This function is called BEFORE the child boundary check in processExpression
|
|
303
|
+
* because JSX elements are NOT scopes - their expressions use variables from
|
|
304
|
+
* the parent scope and should have their conditionals extracted regardless of
|
|
305
|
+
* whether the JSX is within a child boundary.
|
|
306
|
+
*
|
|
307
|
+
* Fix 32: Added parentConditions parameter to track gating conditions from
|
|
308
|
+
* parent && chains. When we find a component nested inside multiple conditionals
|
|
309
|
+
* like `{activeTab && <>{ternary ? ... : <Component />}</>}`, ALL parent
|
|
310
|
+
* conditions should be added as gating conditions for the component.
|
|
311
|
+
*
|
|
312
|
+
* @param node The JSX element, self-closing element, or fragment to traverse
|
|
313
|
+
* @param context The analysis context
|
|
314
|
+
* @param parentConditions Accumulated gating conditions from parent && chains
|
|
315
|
+
*/
|
|
316
|
+
function extractConditionalsFromJsx(node, context, parentConditions = []) {
|
|
317
|
+
// Get children to process
|
|
318
|
+
let children;
|
|
319
|
+
if (ts.isJsxElement(node)) {
|
|
320
|
+
children = node.children;
|
|
321
|
+
}
|
|
322
|
+
else if (ts.isJsxFragment(node)) {
|
|
323
|
+
children = node.children;
|
|
324
|
+
}
|
|
325
|
+
// JsxSelfClosingElement has no children
|
|
326
|
+
if (!children) {
|
|
115
327
|
return;
|
|
116
328
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
329
|
+
for (const child of children) {
|
|
330
|
+
// Process JSX expressions: {expr}
|
|
331
|
+
if (ts.isJsxExpression(child) && child.expression) {
|
|
332
|
+
const expr = unwrapExpression(child.expression);
|
|
333
|
+
// If the expression is an && chain, extract its conditional usages
|
|
334
|
+
if (ts.isBinaryExpression(expr) &&
|
|
335
|
+
expr.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken) {
|
|
336
|
+
// Mark nullable variables
|
|
337
|
+
markConditionVariablesAsNullable(expr, context);
|
|
338
|
+
// Extract conditional usage (this handles compound conditionals)
|
|
339
|
+
// Pass controlsJsxRendering: true since this conditional controls JSX rendering
|
|
340
|
+
extractConditionalUsage(expr, context, 'logical-and', {
|
|
341
|
+
controlsJsxRendering: true,
|
|
342
|
+
});
|
|
343
|
+
// Extract all condition paths from the && chain for gating tracking
|
|
344
|
+
const conditionPaths = extractConditionPathsFromAndChain(expr, context.sourceFile);
|
|
345
|
+
const sourceLocation = getSourceLocation(expr, context.sourceFile);
|
|
346
|
+
// Fix 32: Build accumulated conditions including parent conditions
|
|
347
|
+
const accumulatedConditions = [
|
|
348
|
+
...parentConditions,
|
|
349
|
+
...conditionPaths.map((path) => ({
|
|
350
|
+
path,
|
|
351
|
+
sourceLocation,
|
|
352
|
+
isNegated: false,
|
|
353
|
+
})),
|
|
354
|
+
];
|
|
355
|
+
// Track gating conditions for child components
|
|
356
|
+
// Example: {hasAnalysis && <ScenarioViewer />}
|
|
357
|
+
const jsxElement = findJsxInAndChain(expr);
|
|
358
|
+
if (jsxElement) {
|
|
359
|
+
const componentName = getComponentNameFromJsx(jsxElement);
|
|
360
|
+
if (componentName) {
|
|
361
|
+
// Fix 32: Add ALL accumulated conditions (parent + current) as gating conditions
|
|
362
|
+
for (const condition of accumulatedConditions) {
|
|
363
|
+
context.addChildBoundaryGatingCondition(componentName, {
|
|
364
|
+
path: condition.path,
|
|
365
|
+
conditionType: 'truthiness',
|
|
366
|
+
location: 'logical-and',
|
|
367
|
+
sourceLocation: condition.sourceLocation,
|
|
368
|
+
controlsJsxRendering: true,
|
|
369
|
+
isNegated: condition.isNegated,
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
// Fix 32: Recursively process nested JSX with accumulated conditions
|
|
374
|
+
if (ts.isJsxElement(jsxElement) ||
|
|
375
|
+
ts.isJsxSelfClosingElement(jsxElement)) {
|
|
376
|
+
extractConditionalsFromJsx(jsxElement, context, accumulatedConditions);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
// Fix 32: Also check for nested JSX fragments
|
|
380
|
+
const jsxFragment = findJsxFragmentInAndChain(expr);
|
|
381
|
+
if (jsxFragment) {
|
|
382
|
+
extractConditionalsFromJsx(jsxFragment, context, accumulatedConditions);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
// If the expression is a ternary, extract its conditional
|
|
386
|
+
else if (ts.isConditionalExpression(expr)) {
|
|
387
|
+
// Pass controlsJsxRendering: true since this conditional controls JSX rendering
|
|
388
|
+
extractConditionalUsage(expr.condition, context, 'ternary', {
|
|
389
|
+
controlsJsxRendering: true,
|
|
390
|
+
});
|
|
391
|
+
// Track gating conditions for components in both branches of the ternary
|
|
392
|
+
// Example: {isError ? <ErrorView /> : <SuccessView />}
|
|
393
|
+
const conditionPath = StructuredPath.fromNode(unwrapExpression(expr.condition), context.sourceFile);
|
|
394
|
+
const sourceLocation = getSourceLocation(expr, context.sourceFile);
|
|
395
|
+
// Recursively process the whenTrue and whenFalse branches for JSX
|
|
396
|
+
const whenTrue = unwrapExpression(expr.whenTrue);
|
|
397
|
+
const whenFalse = unwrapExpression(expr.whenFalse);
|
|
398
|
+
// Fix 32: Build conditions for whenTrue branch (parent conditions + ternary condition truthy)
|
|
399
|
+
const whenTrueConditions = [
|
|
400
|
+
...parentConditions,
|
|
401
|
+
...(conditionPath
|
|
402
|
+
? [
|
|
403
|
+
{
|
|
404
|
+
path: conditionPath.toString(),
|
|
405
|
+
sourceLocation,
|
|
406
|
+
isNegated: false,
|
|
407
|
+
},
|
|
408
|
+
]
|
|
409
|
+
: []),
|
|
410
|
+
];
|
|
411
|
+
// Fix 32: Build conditions for whenFalse branch (parent conditions + ternary condition falsy)
|
|
412
|
+
const whenFalseConditions = [
|
|
413
|
+
...parentConditions,
|
|
414
|
+
...(conditionPath
|
|
415
|
+
? [
|
|
416
|
+
{
|
|
417
|
+
path: conditionPath.toString(),
|
|
418
|
+
sourceLocation,
|
|
419
|
+
isNegated: true,
|
|
420
|
+
},
|
|
421
|
+
]
|
|
422
|
+
: []),
|
|
423
|
+
];
|
|
424
|
+
// Handle whenTrue branch (condition is truthy)
|
|
425
|
+
if (ts.isJsxElement(whenTrue) || ts.isJsxSelfClosingElement(whenTrue)) {
|
|
426
|
+
const componentName = getComponentNameFromJsx(whenTrue);
|
|
427
|
+
if (componentName) {
|
|
428
|
+
// Fix 32: Add ALL conditions (parent + ternary) as gating conditions
|
|
429
|
+
for (const condition of whenTrueConditions) {
|
|
430
|
+
context.addChildBoundaryGatingCondition(componentName, {
|
|
431
|
+
path: condition.path,
|
|
432
|
+
conditionType: 'truthiness',
|
|
433
|
+
location: 'ternary',
|
|
434
|
+
sourceLocation: condition.sourceLocation,
|
|
435
|
+
controlsJsxRendering: true,
|
|
436
|
+
isNegated: condition.isNegated,
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
if (ts.isJsxElement(whenTrue) ||
|
|
442
|
+
ts.isJsxSelfClosingElement(whenTrue) ||
|
|
443
|
+
ts.isJsxFragment(whenTrue)) {
|
|
444
|
+
extractConditionalsFromJsx(whenTrue, context, whenTrueConditions);
|
|
445
|
+
}
|
|
446
|
+
// Handle whenFalse branch (condition is falsy/negated)
|
|
447
|
+
if (ts.isJsxElement(whenFalse) ||
|
|
448
|
+
ts.isJsxSelfClosingElement(whenFalse)) {
|
|
449
|
+
const componentName = getComponentNameFromJsx(whenFalse);
|
|
450
|
+
if (componentName) {
|
|
451
|
+
// Fix 32: Add ALL conditions (parent + ternary) as gating conditions
|
|
452
|
+
for (const condition of whenFalseConditions) {
|
|
453
|
+
context.addChildBoundaryGatingCondition(componentName, {
|
|
454
|
+
path: condition.path,
|
|
455
|
+
conditionType: 'truthiness',
|
|
456
|
+
location: 'ternary',
|
|
457
|
+
sourceLocation: condition.sourceLocation,
|
|
458
|
+
controlsJsxRendering: true,
|
|
459
|
+
isNegated: condition.isNegated,
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
if (ts.isJsxElement(whenFalse) ||
|
|
465
|
+
ts.isJsxSelfClosingElement(whenFalse) ||
|
|
466
|
+
ts.isJsxFragment(whenFalse)) {
|
|
467
|
+
extractConditionalsFromJsx(whenFalse, context, whenFalseConditions);
|
|
468
|
+
}
|
|
469
|
+
// Handle chained ternaries: a ? <A/> : b ? <B/> : <C/>
|
|
470
|
+
// When whenFalse is another ConditionalExpression, recursively process it
|
|
471
|
+
else if (ts.isConditionalExpression(whenFalse)) {
|
|
472
|
+
// Extract conditional usage for the nested ternary's condition
|
|
473
|
+
extractConditionalUsage(whenFalse.condition, context, 'ternary', {
|
|
474
|
+
controlsJsxRendering: true,
|
|
475
|
+
});
|
|
476
|
+
// Get the nested condition path
|
|
477
|
+
const nestedConditionPath = StructuredPath.fromNode(unwrapExpression(whenFalse.condition), context.sourceFile);
|
|
478
|
+
const nestedSourceLocation = getSourceLocation(whenFalse, context.sourceFile);
|
|
479
|
+
const nestedWhenTrue = unwrapExpression(whenFalse.whenTrue);
|
|
480
|
+
const nestedWhenFalse = unwrapExpression(whenFalse.whenFalse);
|
|
481
|
+
// Fix 32: Build conditions for nested whenTrue (parent falsy + nested truthy)
|
|
482
|
+
const nestedWhenTrueConditions = [
|
|
483
|
+
...whenFalseConditions, // Parent ternary was falsy to get here
|
|
484
|
+
...(nestedConditionPath
|
|
485
|
+
? [
|
|
486
|
+
{
|
|
487
|
+
path: nestedConditionPath.toString(),
|
|
488
|
+
sourceLocation: nestedSourceLocation,
|
|
489
|
+
isNegated: false,
|
|
490
|
+
},
|
|
491
|
+
]
|
|
492
|
+
: []),
|
|
493
|
+
];
|
|
494
|
+
// Fix 32: Build conditions for nested whenFalse (parent falsy + nested falsy)
|
|
495
|
+
const nestedWhenFalseConditions = [
|
|
496
|
+
...whenFalseConditions, // Parent ternary was falsy to get here
|
|
497
|
+
...(nestedConditionPath
|
|
498
|
+
? [
|
|
499
|
+
{
|
|
500
|
+
path: nestedConditionPath.toString(),
|
|
501
|
+
sourceLocation: nestedSourceLocation,
|
|
502
|
+
isNegated: true,
|
|
503
|
+
},
|
|
504
|
+
]
|
|
505
|
+
: []),
|
|
506
|
+
];
|
|
507
|
+
// Handle nested whenTrue branch
|
|
508
|
+
if (ts.isJsxElement(nestedWhenTrue) ||
|
|
509
|
+
ts.isJsxSelfClosingElement(nestedWhenTrue)) {
|
|
510
|
+
const componentName = getComponentNameFromJsx(nestedWhenTrue);
|
|
511
|
+
if (componentName) {
|
|
512
|
+
// Fix 32: Add ALL accumulated conditions
|
|
513
|
+
for (const condition of nestedWhenTrueConditions) {
|
|
514
|
+
context.addChildBoundaryGatingCondition(componentName, {
|
|
515
|
+
path: condition.path,
|
|
516
|
+
conditionType: 'truthiness',
|
|
517
|
+
location: 'ternary',
|
|
518
|
+
sourceLocation: condition.sourceLocation,
|
|
519
|
+
controlsJsxRendering: true,
|
|
520
|
+
isNegated: condition.isNegated,
|
|
521
|
+
});
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
if (ts.isJsxElement(nestedWhenTrue) ||
|
|
526
|
+
ts.isJsxSelfClosingElement(nestedWhenTrue) ||
|
|
527
|
+
ts.isJsxFragment(nestedWhenTrue)) {
|
|
528
|
+
extractConditionalsFromJsx(nestedWhenTrue, context, nestedWhenTrueConditions);
|
|
529
|
+
}
|
|
530
|
+
// Handle nested whenFalse branch (this could be another chained ternary or JSX)
|
|
531
|
+
if (ts.isJsxElement(nestedWhenFalse) ||
|
|
532
|
+
ts.isJsxSelfClosingElement(nestedWhenFalse)) {
|
|
533
|
+
const componentName = getComponentNameFromJsx(nestedWhenFalse);
|
|
534
|
+
if (componentName) {
|
|
535
|
+
// Fix 32: Add ALL accumulated conditions
|
|
536
|
+
for (const condition of nestedWhenFalseConditions) {
|
|
537
|
+
context.addChildBoundaryGatingCondition(componentName, {
|
|
538
|
+
path: condition.path,
|
|
539
|
+
conditionType: 'truthiness',
|
|
540
|
+
location: 'ternary',
|
|
541
|
+
sourceLocation: condition.sourceLocation,
|
|
542
|
+
controlsJsxRendering: true,
|
|
543
|
+
isNegated: condition.isNegated,
|
|
544
|
+
});
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
if (ts.isJsxElement(nestedWhenFalse) ||
|
|
549
|
+
ts.isJsxSelfClosingElement(nestedWhenFalse) ||
|
|
550
|
+
ts.isJsxFragment(nestedWhenFalse)) {
|
|
551
|
+
extractConditionalsFromJsx(nestedWhenFalse, context, nestedWhenFalseConditions);
|
|
552
|
+
}
|
|
553
|
+
// If nestedWhenFalse is yet another ConditionalExpression, the recursion
|
|
554
|
+
// will handle it on the next iteration when this function processes it
|
|
555
|
+
else if (ts.isConditionalExpression(nestedWhenFalse)) {
|
|
556
|
+
// Recursively handle deeper nesting by wrapping in a synthetic process
|
|
557
|
+
// We create a fake JsxExpression context to reuse the same logic
|
|
558
|
+
const syntheticChild = {
|
|
559
|
+
kind: ts.SyntaxKind.JsxExpression,
|
|
560
|
+
expression: nestedWhenFalse,
|
|
561
|
+
};
|
|
562
|
+
// Process via the main JSX expression handler by recursing
|
|
563
|
+
// For now, just extract conditionals directly
|
|
564
|
+
extractConditionalUsage(nestedWhenFalse.condition, context, 'ternary', { controlsJsxRendering: true });
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
// Recursively process nested JSX elements - Fix 32: pass parent conditions
|
|
570
|
+
else if (ts.isJsxElement(child)) {
|
|
571
|
+
extractConditionalsFromJsx(child, context, parentConditions);
|
|
572
|
+
}
|
|
573
|
+
// Recursively process nested JSX fragments - Fix 32: pass parent conditions
|
|
574
|
+
else if (ts.isJsxFragment(child)) {
|
|
575
|
+
extractConditionalsFromJsx(child, context, parentConditions);
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
/**
|
|
580
|
+
* Extracts conditional usages from a condition expression for key attribute detection.
|
|
581
|
+
* This function identifies which attributes are used in conditionals and how they're used.
|
|
582
|
+
* It also tracks compound conditionals (&&-chains) where all conditions must be true together.
|
|
583
|
+
*
|
|
584
|
+
* @param condition The condition expression to analyze
|
|
585
|
+
* @param context The analysis context
|
|
586
|
+
* @param location Where this condition appears (if, ternary, logical-and, switch)
|
|
587
|
+
* @param options Additional options including controlsJsxRendering flag
|
|
588
|
+
*/
|
|
589
|
+
export function extractConditionalUsage(condition, context, location, options = {}) {
|
|
590
|
+
const { controlsJsxRendering } = options;
|
|
591
|
+
// Internal recursive function with chain tracking
|
|
592
|
+
function extractWithChainTracking(expr, chainInfo, isNegated) {
|
|
593
|
+
const unwrapped = unwrapExpression(expr);
|
|
594
|
+
// Handle binary expressions with && (logical AND chains)
|
|
595
|
+
// Example: `a && b && <Component />` - both a and b are conditional checks
|
|
596
|
+
if (ts.isBinaryExpression(unwrapped) &&
|
|
597
|
+
unwrapped.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken) {
|
|
598
|
+
// Track if we're creating the chain at this level (root of the chain)
|
|
599
|
+
const isChainRoot = !chainInfo;
|
|
600
|
+
// If no chainInfo, this is the root of a new chain
|
|
601
|
+
if (isChainRoot) {
|
|
602
|
+
const chainLength = countConditionsInAndChain(unwrapped);
|
|
603
|
+
// Only create chain tracking for chains with 2+ conditions
|
|
604
|
+
if (chainLength >= 2) {
|
|
605
|
+
const chainId = `chain_${crypto.randomUUID().slice(0, 8)}`;
|
|
606
|
+
const chainExpression = unwrapped.getText(context.sourceFile);
|
|
607
|
+
const compound = {
|
|
608
|
+
chainId,
|
|
609
|
+
expression: chainExpression.length > 200
|
|
610
|
+
? chainExpression.slice(0, 200) + '...'
|
|
611
|
+
: chainExpression,
|
|
612
|
+
conditions: [],
|
|
613
|
+
location,
|
|
614
|
+
sourceLocation: getSourceLocation(unwrapped, context.sourceFile),
|
|
615
|
+
controlsJsxRendering,
|
|
616
|
+
};
|
|
617
|
+
chainInfo = {
|
|
618
|
+
chainId,
|
|
619
|
+
chainLength,
|
|
620
|
+
chainExpression: compound.expression,
|
|
621
|
+
currentPosition: 0,
|
|
622
|
+
compound,
|
|
623
|
+
};
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
// Recursively process left side
|
|
627
|
+
extractWithChainTracking(unwrapped.left, chainInfo, false);
|
|
628
|
+
// Process right side if it's not JSX (JSX is the consequence, not the condition)
|
|
629
|
+
const rightUnwrapped = unwrapExpression(unwrapped.right);
|
|
630
|
+
const isJsxConsequence = ts.isJsxElement(rightUnwrapped) ||
|
|
631
|
+
ts.isJsxSelfClosingElement(rightUnwrapped) ||
|
|
632
|
+
ts.isJsxFragment(rightUnwrapped);
|
|
633
|
+
if (!isJsxConsequence) {
|
|
634
|
+
extractWithChainTracking(unwrapped.right, chainInfo, false);
|
|
635
|
+
}
|
|
636
|
+
// If this is the root of the chain, register the compound conditional
|
|
637
|
+
if (isChainRoot && chainInfo) {
|
|
638
|
+
context.addCompoundConditional(chainInfo.compound);
|
|
639
|
+
}
|
|
133
640
|
return;
|
|
134
641
|
}
|
|
135
|
-
//
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
location,
|
|
143
|
-
});
|
|
642
|
+
// Handle binary expressions with || (logical OR)
|
|
643
|
+
// OR breaks the chain - each side is independent
|
|
644
|
+
if (ts.isBinaryExpression(unwrapped) &&
|
|
645
|
+
unwrapped.operatorToken.kind === ts.SyntaxKind.BarBarToken) {
|
|
646
|
+
// Both sides of || are independent conditional checks (no chain tracking)
|
|
647
|
+
extractWithChainTracking(unwrapped.left, null, false);
|
|
648
|
+
extractWithChainTracking(unwrapped.right, null, false);
|
|
144
649
|
return;
|
|
145
650
|
}
|
|
146
|
-
//
|
|
147
|
-
if (
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
651
|
+
// Handle comparison operators (===, !==, <, >, <=, >=)
|
|
652
|
+
// Example: `if (status === 'active')` - status is compared against 'active'
|
|
653
|
+
if (ts.isBinaryExpression(unwrapped) &&
|
|
654
|
+
isComparisonOperator(unwrapped.operatorToken.kind)) {
|
|
655
|
+
// Try to extract the variable and the compared value
|
|
656
|
+
const leftPath = StructuredPath.fromNode(unwrapped.left, context.sourceFile);
|
|
657
|
+
const rightPath = StructuredPath.fromNode(unwrapped.right, context.sourceFile);
|
|
658
|
+
// Determine the compared value for computing requiredValue
|
|
659
|
+
const getRequiredValue = (literalValue, isNegatedComparison) => {
|
|
660
|
+
if (literalValue === undefined)
|
|
661
|
+
return undefined;
|
|
662
|
+
// For !== comparisons, the condition is true when NOT equal to the value
|
|
663
|
+
// For === comparisons, the condition is true when equal to the value
|
|
664
|
+
const isNotEqual = unwrapped.operatorToken.kind ===
|
|
665
|
+
ts.SyntaxKind.ExclamationEqualsEqualsToken ||
|
|
666
|
+
unwrapped.operatorToken.kind === ts.SyntaxKind.ExclamationEqualsToken;
|
|
667
|
+
if (isNotEqual) {
|
|
668
|
+
// !== 'value' means requiredValue is NOT 'value', but we express this as "not 'value'"
|
|
669
|
+
return `not ${literalValue}`;
|
|
670
|
+
}
|
|
671
|
+
return literalValue;
|
|
672
|
+
};
|
|
673
|
+
// Helper to add a condition
|
|
674
|
+
const addCondition = (path, conditionType, comparedValues, requiredValue) => {
|
|
675
|
+
const usage = {
|
|
676
|
+
path,
|
|
677
|
+
conditionType,
|
|
678
|
+
comparedValues,
|
|
679
|
+
location,
|
|
680
|
+
sourceLocation: getSourceLocation(unwrapped, context.sourceFile),
|
|
681
|
+
isNegated,
|
|
682
|
+
controlsJsxRendering,
|
|
683
|
+
};
|
|
684
|
+
// Add chain info if part of a compound conditional
|
|
685
|
+
if (chainInfo) {
|
|
686
|
+
usage.chainId = chainInfo.chainId;
|
|
687
|
+
usage.chainPosition = chainInfo.currentPosition;
|
|
688
|
+
usage.chainLength = chainInfo.chainLength;
|
|
689
|
+
usage.chainExpression = chainInfo.chainExpression;
|
|
690
|
+
chainInfo.currentPosition++;
|
|
691
|
+
// Add to compound conditional conditions
|
|
692
|
+
chainInfo.compound.conditions.push({
|
|
693
|
+
path,
|
|
694
|
+
conditionType,
|
|
695
|
+
comparedValues,
|
|
696
|
+
isNegated,
|
|
697
|
+
requiredValue,
|
|
698
|
+
});
|
|
699
|
+
}
|
|
700
|
+
context.addConditionalUsage(usage);
|
|
701
|
+
};
|
|
702
|
+
// Check if left is a variable and right is a literal
|
|
703
|
+
if (leftPath && isLiteralExpression(unwrapped.right)) {
|
|
704
|
+
const literalValue = getLiteralValue(unwrapped.right, context);
|
|
705
|
+
addCondition(leftPath.toLeftHandSideString(), 'comparison', literalValue !== undefined ? [literalValue] : undefined, getRequiredValue(literalValue, isNegated));
|
|
706
|
+
return;
|
|
707
|
+
}
|
|
708
|
+
// Check if right is a variable and left is a literal
|
|
709
|
+
if (rightPath && isLiteralExpression(unwrapped.left)) {
|
|
710
|
+
const literalValue = getLiteralValue(unwrapped.left, context);
|
|
711
|
+
addCondition(rightPath.toLeftHandSideString(), 'comparison', literalValue !== undefined ? [literalValue] : undefined, getRequiredValue(literalValue, isNegated));
|
|
712
|
+
return;
|
|
713
|
+
}
|
|
714
|
+
// Both sides are variables - record both as comparisons without specific values
|
|
715
|
+
if (leftPath) {
|
|
716
|
+
addCondition(leftPath.toLeftHandSideString(), 'comparison');
|
|
717
|
+
}
|
|
718
|
+
if (rightPath) {
|
|
719
|
+
addCondition(rightPath.toLeftHandSideString(), 'comparison');
|
|
720
|
+
}
|
|
721
|
+
return;
|
|
722
|
+
}
|
|
723
|
+
// Handle prefix unary NOT expression: !variable
|
|
724
|
+
// Example: `if (!isVisible)` - isVisible is a truthiness check (negated)
|
|
725
|
+
if (ts.isPrefixUnaryExpression(unwrapped) &&
|
|
726
|
+
unwrapped.operator === ts.SyntaxKind.ExclamationToken) {
|
|
727
|
+
extractWithChainTracking(unwrapped.operand, chainInfo, !isNegated);
|
|
728
|
+
return;
|
|
153
729
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
730
|
+
// Handle simple identifiers or property accesses (truthiness checks)
|
|
731
|
+
// Example: `if (x)` or `x && <JSX />` - x is checked for truthiness
|
|
732
|
+
const path = StructuredPath.fromNode(unwrapped, context.sourceFile);
|
|
733
|
+
if (path && !path.isLiteral()) {
|
|
734
|
+
const pathStr = path.toLeftHandSideString();
|
|
735
|
+
const usage = {
|
|
736
|
+
path: pathStr,
|
|
737
|
+
conditionType: 'truthiness',
|
|
158
738
|
location,
|
|
159
|
-
|
|
739
|
+
sourceLocation: getSourceLocation(unwrapped, context.sourceFile),
|
|
740
|
+
isNegated,
|
|
741
|
+
controlsJsxRendering,
|
|
742
|
+
};
|
|
743
|
+
// Add chain info if part of a compound conditional
|
|
744
|
+
if (chainInfo) {
|
|
745
|
+
usage.chainId = chainInfo.chainId;
|
|
746
|
+
usage.chainPosition = chainInfo.currentPosition;
|
|
747
|
+
usage.chainLength = chainInfo.chainLength;
|
|
748
|
+
usage.chainExpression = chainInfo.chainExpression;
|
|
749
|
+
chainInfo.currentPosition++;
|
|
750
|
+
// Add to compound conditional conditions
|
|
751
|
+
// For truthiness, requiredValue is true if not negated, false if negated
|
|
752
|
+
chainInfo.compound.conditions.push({
|
|
753
|
+
path: pathStr,
|
|
754
|
+
conditionType: 'truthiness',
|
|
755
|
+
isNegated,
|
|
756
|
+
requiredValue: !isNegated,
|
|
757
|
+
});
|
|
758
|
+
}
|
|
759
|
+
context.addConditionalUsage(usage);
|
|
160
760
|
}
|
|
161
|
-
return;
|
|
162
|
-
}
|
|
163
|
-
// Handle prefix unary NOT expression: !variable
|
|
164
|
-
// Example: `if (!isVisible)` - isVisible is a truthiness check
|
|
165
|
-
if (ts.isPrefixUnaryExpression(unwrapped) &&
|
|
166
|
-
unwrapped.operator === ts.SyntaxKind.ExclamationToken) {
|
|
167
|
-
extractConditionalUsage(unwrapped.operand, context, location);
|
|
168
|
-
return;
|
|
169
|
-
}
|
|
170
|
-
// Handle simple identifiers or property accesses (truthiness checks)
|
|
171
|
-
// Example: `if (x)` or `x && <JSX />` - x is checked for truthiness
|
|
172
|
-
const path = StructuredPath.fromNode(unwrapped, context.sourceFile);
|
|
173
|
-
if (path && !path.isLiteral()) {
|
|
174
|
-
context.addConditionalUsage({
|
|
175
|
-
path: path.toLeftHandSideString(),
|
|
176
|
-
conditionType: 'truthiness',
|
|
177
|
-
location,
|
|
178
|
-
});
|
|
179
761
|
}
|
|
762
|
+
// Start extraction with no chain info
|
|
763
|
+
extractWithChainTracking(condition, null, false);
|
|
180
764
|
}
|
|
181
765
|
/**
|
|
182
766
|
* Helper to check if an expression is a literal value
|
|
@@ -254,7 +838,24 @@ export function processExpression({ node, context, targetPath, typeHint, }) {
|
|
|
254
838
|
unwrappedNode.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken) {
|
|
255
839
|
markConditionVariablesAsNullable(unwrappedNode, context);
|
|
256
840
|
// Extract conditional usages for key attribute detection
|
|
257
|
-
|
|
841
|
+
// Only call from the OUTERMOST && expression to avoid duplicates
|
|
842
|
+
// Check if parent is also a && (meaning we're nested)
|
|
843
|
+
const parent = unwrappedNode.parent;
|
|
844
|
+
const parentIsAndChain = parent &&
|
|
845
|
+
ts.isBinaryExpression(parent) &&
|
|
846
|
+
parent.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken;
|
|
847
|
+
if (!parentIsAndChain) {
|
|
848
|
+
extractConditionalUsage(unwrappedNode, context, 'logical-and');
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
// CRITICAL: Extract conditionals from JSX BEFORE checking child boundaries
|
|
852
|
+
// JSX elements are NOT scopes - their expressions use variables from the parent scope.
|
|
853
|
+
// Even if the JSX element is within a child boundary (e.g., because it contains callbacks),
|
|
854
|
+
// we must still extract conditionals from JSX expression children like {x && <div>...</div>}
|
|
855
|
+
if (ts.isJsxElement(unwrappedNode) ||
|
|
856
|
+
ts.isJsxSelfClosingElement(unwrappedNode) ||
|
|
857
|
+
ts.isJsxFragment(unwrappedNode)) {
|
|
858
|
+
extractConditionalsFromJsx(unwrappedNode, context);
|
|
258
859
|
}
|
|
259
860
|
// If the node falls within an excluded child scope, stop processing it.
|
|
260
861
|
if (context.isChildBoundary(node)) {
|
|
@@ -386,7 +987,8 @@ export function processExpression({ node, context, targetPath, typeHint, }) {
|
|
|
386
987
|
const propertyPath = objectPath.withProperty(unwrappedNode.name.text);
|
|
387
988
|
// Check if this is an environment variable access
|
|
388
989
|
const fullText = unwrappedNode.getText(context.sourceFile);
|
|
389
|
-
if (fullText.includes('.env.') //
|
|
990
|
+
if (fullText.includes('.env.') || // process.env.X, window.env.X
|
|
991
|
+
isEnvStoreAccess(fullText) // env.X where env is likely an env config object
|
|
390
992
|
) {
|
|
391
993
|
context.addEnvironmentVariable(fullText);
|
|
392
994
|
}
|
|
@@ -610,6 +1212,13 @@ export function processExpression({ node, context, targetPath, typeHint, }) {
|
|
|
610
1212
|
// e.g., `const tab = segments[0] || 'default'` should trace tab back to segments[0]
|
|
611
1213
|
if (operatorKind === ts.SyntaxKind.QuestionQuestionToken) {
|
|
612
1214
|
// specifically for ?? we create an equivalence to the left side
|
|
1215
|
+
// IMPORTANT: Also process the left side recursively to apply method semantics
|
|
1216
|
+
// (e.g., for `const segments = splat?.split('/') ?? []`, we need split semantics)
|
|
1217
|
+
processExpression({
|
|
1218
|
+
node: unwrappedNode.left,
|
|
1219
|
+
context,
|
|
1220
|
+
// Don't pass targetPath here - we'll establish equivalence separately below
|
|
1221
|
+
});
|
|
613
1222
|
if (targetPath) {
|
|
614
1223
|
resultPath = StructuredPath.fromNode(unwrappedNode.left, context.sourceFile);
|
|
615
1224
|
}
|
|
@@ -666,9 +1275,10 @@ export function processExpression({ node, context, targetPath, typeHint, }) {
|
|
|
666
1275
|
context.markUnsupported(unwrappedNode.expression, `processExpression: Couldn't get path for called expression: ${ts.SyntaxKind[unwrappedNode.expression.kind]}`, false);
|
|
667
1276
|
return false;
|
|
668
1277
|
}
|
|
669
|
-
//
|
|
670
|
-
//
|
|
671
|
-
|
|
1278
|
+
// Build call path using original source text for consistent schema paths.
|
|
1279
|
+
// IMPORTANT: Never use cyScope names in call paths - they are internal identifiers
|
|
1280
|
+
// that should not appear in schema paths or call signatures.
|
|
1281
|
+
const callPath = buildCallPathFromSource(unwrappedNode, context);
|
|
672
1282
|
// 2. Process all arguments recursively WITH targetPath for proper equivalence
|
|
673
1283
|
for (let i = 0; i < unwrappedNode.arguments.length; i++) {
|
|
674
1284
|
const arg = unwrappedNode.arguments[i];
|
|
@@ -798,6 +1408,12 @@ export function processExpression({ node, context, targetPath, typeHint, }) {
|
|
|
798
1408
|
}
|
|
799
1409
|
// Create a path for this property within the base
|
|
800
1410
|
const propPath = targetPath.withProperty(propName);
|
|
1411
|
+
// Handle child boundaries (callback functions) in object properties
|
|
1412
|
+
// This establishes equivalency between the property path and the child scope
|
|
1413
|
+
// e.g., columns[0].renderCell → cyScope1()
|
|
1414
|
+
if (context.isChildBoundary(property.initializer)) {
|
|
1415
|
+
context.addChildBoundaryEquivalence(propPath, property.initializer);
|
|
1416
|
+
}
|
|
801
1417
|
// Process the property value with propPath as targetPath
|
|
802
1418
|
// This allows nested object literals to work correctly
|
|
803
1419
|
processExpression({
|
|
@@ -1032,14 +1648,24 @@ export function processExpression({ node, context, targetPath, typeHint, }) {
|
|
|
1032
1648
|
markConditionVariablesAsNullable(unwrappedNode.condition, context);
|
|
1033
1649
|
// Extract conditional usages for key attribute detection
|
|
1034
1650
|
extractConditionalUsage(unwrappedNode.condition, context, 'ternary');
|
|
1651
|
+
// Extract conditional effects (setter calls in ternary branches)
|
|
1652
|
+
const knownSetters = findUseStateSetters(context.sourceFile);
|
|
1653
|
+
const effects = extractConditionalEffectsFromTernary(unwrappedNode, context, knownSetters);
|
|
1654
|
+
for (const effect of effects) {
|
|
1655
|
+
context.addConditionalEffect(effect);
|
|
1656
|
+
}
|
|
1035
1657
|
// Process all parts recursively
|
|
1036
1658
|
processExpression({
|
|
1037
1659
|
node: unwrappedNode.condition,
|
|
1038
1660
|
context,
|
|
1039
1661
|
typeHint: 'boolean | unknown',
|
|
1040
1662
|
}); //TODO: could we capture that this is evidence of a boolean type?
|
|
1041
|
-
|
|
1042
|
-
|
|
1663
|
+
// Process both branches WITH targetPath to establish equivalencies
|
|
1664
|
+
// This is critical for tracing nested properties through ternary assignments
|
|
1665
|
+
// e.g., const items = condition ? arr1 : arr2; items.map(i => i.prop)
|
|
1666
|
+
// We need items to be equivalent to both arr1 AND arr2 for proper tracing
|
|
1667
|
+
processExpression({ node: unwrappedNode.whenTrue, context, targetPath });
|
|
1668
|
+
processExpression({ node: unwrappedNode.whenFalse, context, targetPath });
|
|
1043
1669
|
// Create a path for the whole expression
|
|
1044
1670
|
const expressionSourcePath = nodeToSource(unwrappedNode, context.sourceFile);
|
|
1045
1671
|
// Infer type based on branches
|
|
@@ -1054,10 +1680,22 @@ export function processExpression({ node, context, targetPath, typeHint, }) {
|
|
|
1054
1680
|
}
|
|
1055
1681
|
// Register type for the expression
|
|
1056
1682
|
context.addType(expressionSourcePath, resultType);
|
|
1057
|
-
// If targetPath is provided,
|
|
1683
|
+
// If targetPath is provided, only register type (don't overwrite branch equivalencies)
|
|
1684
|
+
// The equivalencies to individual branches (set above) are more useful for tracing
|
|
1685
|
+
// than an equivalency to the entire ternary expression text
|
|
1058
1686
|
if (targetPath) {
|
|
1059
|
-
|
|
1060
|
-
|
|
1687
|
+
// NOTE: We intentionally do NOT add equivalence here.
|
|
1688
|
+
// The branch processing above already added equivalencies:
|
|
1689
|
+
// targetPath -> whenTrue branch
|
|
1690
|
+
// targetPath -> whenFalse branch
|
|
1691
|
+
// Adding an equivalence to expressionSourcePath would overwrite those
|
|
1692
|
+
// with a useless equivalence to the ternary text itself.
|
|
1693
|
+
//
|
|
1694
|
+
// Use updateSchemaType instead of addType because:
|
|
1695
|
+
// 1. Branch processing may have already set a type on targetPath
|
|
1696
|
+
// 2. addType has a guard that prevents overwriting specific types with 'unknown'
|
|
1697
|
+
// 3. updateSchemaType bypasses this guard, ensuring the ternary's computed type is used
|
|
1698
|
+
context.updateSchemaType(targetPath, resultType);
|
|
1061
1699
|
}
|
|
1062
1700
|
return true;
|
|
1063
1701
|
}
|
|
@@ -1618,6 +2256,9 @@ function processJsxAttribute(attr, context, componentPath, targetPath) {
|
|
|
1618
2256
|
if (ts.isJsxExpression(attr.initializer) && attr.initializer.expression) {
|
|
1619
2257
|
const expression = attr.initializer.expression;
|
|
1620
2258
|
if (context.isChildBoundary(expression)) {
|
|
2259
|
+
// Create equivalency between attribute path and child scope
|
|
2260
|
+
// e.g., Grid().signature[0].renderRow → cyScope1()
|
|
2261
|
+
context.addChildBoundaryEquivalence(attributePath, expression);
|
|
1621
2262
|
return true;
|
|
1622
2263
|
}
|
|
1623
2264
|
// Process the expression with attributePath as targetPath
|