@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,12 +1,93 @@
|
|
|
1
1
|
import { joinParenthesesAndArrays, splitOutsideParenthesesAndArrays, functionArguments, cleanOutBoundary, fillInDirectSchemaGapsAndUnknowns, removeDuplicateFunctionCalls, } from "../../../../../packages/ai/index.js";
|
|
2
2
|
/**
|
|
3
|
-
* Converts a
|
|
4
|
-
*
|
|
3
|
+
* Converts a call signature to a valid JavaScript identifier (function name).
|
|
4
|
+
* The original signature is preserved for data access - this only creates the function name.
|
|
5
|
+
*
|
|
6
|
+
* Examples:
|
|
7
|
+
* - "useAuth()" → "useAuth"
|
|
8
|
+
* - "db.select(usersQuery)" → "db_select_usersQuery"
|
|
9
|
+
* - "db.select(postsQuery)" → "db_select_postsQuery"
|
|
10
|
+
* - "useFetcher<User>()" → "useFetcher_User"
|
|
11
|
+
* - "useFetcher<{ data: UserData | null }>()" → "useFetcher_data_UserData_null"
|
|
12
|
+
* - "eq('user_id', value)" → "eq_user_id_value"
|
|
13
|
+
* - "from('workouts')" → "from_workouts"
|
|
5
14
|
*/
|
|
6
|
-
function
|
|
7
|
-
//
|
|
8
|
-
|
|
9
|
-
|
|
15
|
+
function callSignatureToFunctionName(signature) {
|
|
16
|
+
// Extract components from the signature
|
|
17
|
+
const components = [];
|
|
18
|
+
// 1. Extract function path (parts separated by dots outside parens/brackets)
|
|
19
|
+
const pathMatch = signature.match(/^([^<(]+)/);
|
|
20
|
+
if (pathMatch) {
|
|
21
|
+
const path = pathMatch[1];
|
|
22
|
+
// Split on dots but preserve the parts
|
|
23
|
+
components.push(...path.split('.').filter(Boolean));
|
|
24
|
+
}
|
|
25
|
+
// 2. Extract generic type parameters (content between < and >)
|
|
26
|
+
const genericMatch = signature.match(/<([^>]+)>/);
|
|
27
|
+
if (genericMatch) {
|
|
28
|
+
const genericContent = genericMatch[1];
|
|
29
|
+
// Extract meaningful identifiers from generic type
|
|
30
|
+
// Handle complex types like "{ data: UserData | null }"
|
|
31
|
+
const typeIdentifiers = genericContent
|
|
32
|
+
.replace(/[{}:;,]/g, ' ') // Remove structural chars
|
|
33
|
+
.replace(/\|/g, ' ') // Handle union types
|
|
34
|
+
.split(/\s+/)
|
|
35
|
+
.filter(Boolean)
|
|
36
|
+
.filter((s) => /^[A-Za-z_][A-Za-z0-9_]*$/.test(s)) // Only valid identifiers
|
|
37
|
+
.filter((s) => ![
|
|
38
|
+
'null',
|
|
39
|
+
'undefined',
|
|
40
|
+
'void',
|
|
41
|
+
'never',
|
|
42
|
+
'any',
|
|
43
|
+
'unknown',
|
|
44
|
+
'data',
|
|
45
|
+
'typeof',
|
|
46
|
+
].includes(s)); // Skip common non-meaningful keywords
|
|
47
|
+
if (typeIdentifiers.length > 0) {
|
|
48
|
+
components.push(...typeIdentifiers.slice(0, 2)); // Limit to first 2 for reasonable length
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// 3. Extract function arguments (first 2 for disambiguation)
|
|
52
|
+
const argsMatch = signature.match(/\(([^)]*)\)/);
|
|
53
|
+
if (argsMatch && argsMatch[1]) {
|
|
54
|
+
const argsContent = argsMatch[1].trim();
|
|
55
|
+
if (argsContent) {
|
|
56
|
+
const args = argsContent.split(',').map((arg) => arg.trim());
|
|
57
|
+
for (const arg of args.slice(0, 2)) {
|
|
58
|
+
// For quoted strings, extract the content
|
|
59
|
+
const stringMatch = arg.match(/^['"`](.+)['"`]$/);
|
|
60
|
+
if (stringMatch) {
|
|
61
|
+
// Split on dots for string paths like 'users.id'
|
|
62
|
+
const parts = stringMatch[1].split('.').filter(Boolean);
|
|
63
|
+
components.push(...parts);
|
|
64
|
+
}
|
|
65
|
+
else if (/^[A-Za-z_][A-Za-z0-9_]*$/.test(arg)) {
|
|
66
|
+
// Valid identifier - use as-is
|
|
67
|
+
components.push(arg);
|
|
68
|
+
}
|
|
69
|
+
else if (/^\d+$/.test(arg)) {
|
|
70
|
+
// Number - use as-is
|
|
71
|
+
components.push(arg);
|
|
72
|
+
}
|
|
73
|
+
// Skip complex expressions
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// Build the function name from components
|
|
78
|
+
const functionName = components
|
|
79
|
+
.join('_')
|
|
80
|
+
.replace(/[^a-zA-Z0-9_]/g, '_') // Sanitize special chars
|
|
81
|
+
.replace(/_+/g, '_') // Collapse multiple underscores
|
|
82
|
+
.replace(/^_|_$/g, ''); // Trim underscores
|
|
83
|
+
return functionName || 'mock';
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Check if a mock name is a call signature (e.g., "useFetcher<User>()", "db.select(query)")
|
|
87
|
+
*/
|
|
88
|
+
function isCallSignature(mockName) {
|
|
89
|
+
// Call signatures contain parentheses (function calls)
|
|
90
|
+
return mockName.includes('(');
|
|
10
91
|
}
|
|
11
92
|
/**
|
|
12
93
|
* Extract property names that are jsx-components and should be preserved from original.
|
|
@@ -134,23 +215,30 @@ function funcArgs(functionSignature) {
|
|
|
134
215
|
}
|
|
135
216
|
// isValidKey ensures that the key does not contain any characters that would make it invalid in a JavaScript object.
|
|
136
217
|
// For example, it should not contain spaces, special characters, or start with a number.
|
|
218
|
+
// Also rejects keys that are pure function calls like "()" or "(args)" - these aren't property names.
|
|
137
219
|
function isValidKey(key) {
|
|
138
220
|
if (!key || key.length === 0)
|
|
139
221
|
return false;
|
|
140
222
|
const keyWithOutArguments = key.split('(')[0];
|
|
223
|
+
// Reject empty keys (happens when key is "()" or "(args)") - these are function calls, not property names
|
|
224
|
+
if (!keyWithOutArguments || keyWithOutArguments.length === 0)
|
|
225
|
+
return false;
|
|
141
226
|
return !/\s/.test(keyWithOutArguments);
|
|
142
227
|
}
|
|
143
|
-
export default function constructMockCode(mockName, dependencySchemas, entityType,
|
|
144
|
-
|
|
145
|
-
//
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
228
|
+
export default function constructMockCode(mockName, dependencySchemas, entityType, _canonicalKey, // DEPRECATED: No longer used, kept for API compatibility
|
|
229
|
+
options) {
|
|
230
|
+
// Check if mockName is a call signature (e.g., "useFetcher<User>()", "db.select(query)")
|
|
231
|
+
const mockNameIsCallSignature = isCallSignature(mockName);
|
|
232
|
+
// For call signatures, use the original signature for data access but generate
|
|
233
|
+
// a valid JS function name from it
|
|
234
|
+
const derivedFunctionName = mockNameIsCallSignature
|
|
235
|
+
? callSignatureToFunctionName(mockName)
|
|
150
236
|
: null;
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
237
|
+
// The baseMockName is the function name without type params and args
|
|
238
|
+
// e.g., "useFetcher<User>()" -> "useFetcher", "db.select(query)" -> "db"
|
|
239
|
+
const baseMockName = mockName.split(/[<(]/)[0];
|
|
240
|
+
// The data key is the mockName (call signature) for data access
|
|
241
|
+
let dataKey;
|
|
154
242
|
const mockNameParts = splitOutsideParenthesesAndArrays(baseMockName);
|
|
155
243
|
let relevantReturnValueSchema;
|
|
156
244
|
let dataStructurePath;
|
|
@@ -159,26 +247,9 @@ export default function constructMockCode(mockName, dependencySchemas, entityTyp
|
|
|
159
247
|
let signatureSchema;
|
|
160
248
|
for (const filePath in dependencySchemas) {
|
|
161
249
|
for (const entityName in dependencySchemas[filePath]) {
|
|
162
|
-
//
|
|
163
|
-
|
|
164
|
-
const
|
|
165
|
-
? `${variableQualifier} <- ${baseMockName}`
|
|
166
|
-
: mockNameParts[0];
|
|
167
|
-
// Check for direct match
|
|
168
|
-
let matches = entityName === targetEntityName || entityName === mockNameParts[0];
|
|
169
|
-
// If no direct match and no qualifier was provided, check if the entity
|
|
170
|
-
// is stored under a variable-qualified key (e.g., "stateBadge <- getStateBadge")
|
|
171
|
-
// This handles the case where gatherDataForMocks stored the entity with a variable
|
|
172
|
-
// qualifier but writeScenarioComponents called constructMockCode without one.
|
|
173
|
-
if (!matches && !variableQualifier) {
|
|
174
|
-
const qualifiedKeyMatch = entityName.match(new RegExp(`^([a-zA-Z_][a-zA-Z0-9_]*)\\s*<-\\s*${mockNameParts[0]}$`));
|
|
175
|
-
if (qualifiedKeyMatch) {
|
|
176
|
-
matches = true;
|
|
177
|
-
// Extract the variable qualifier from the entity name so we can use
|
|
178
|
-
// it for the data lookup key later
|
|
179
|
-
variableQualifier = qualifiedKeyMatch[1];
|
|
180
|
-
}
|
|
181
|
-
}
|
|
250
|
+
// Match entity by base name (without generics/args)
|
|
251
|
+
const entityBaseName = entityName.split(/[<(]/)[0];
|
|
252
|
+
const matches = entityBaseName === baseMockName || entityName === mockNameParts[0];
|
|
182
253
|
if (!matches)
|
|
183
254
|
continue;
|
|
184
255
|
// Track if we found the entity and it has a signature (is a function)
|
|
@@ -210,6 +281,39 @@ export default function constructMockCode(mockName, dependencySchemas, entityTyp
|
|
|
210
281
|
}
|
|
211
282
|
}
|
|
212
283
|
}
|
|
284
|
+
// Check if the entity is used as a function (called with ()) vs an object/namespace.
|
|
285
|
+
// Look for paths in the schema that start with "baseMockName(" or "baseMockName<" indicating function calls.
|
|
286
|
+
// The "<" handles generic type parameters like useLoaderData<T>().
|
|
287
|
+
// Also check dataStructurePath === 'returnValue' which indicates a function return value.
|
|
288
|
+
const entityIsFunction = foundEntityWithSignature ||
|
|
289
|
+
dataStructurePath === 'returnValue' ||
|
|
290
|
+
Object.keys(relevantReturnValueSchema ?? {}).some((key) => key.startsWith(`${baseMockName}(`) ||
|
|
291
|
+
key.startsWith(`${baseMockName}<`));
|
|
292
|
+
// Calculate the data key - use the call signature (mockName) for data access
|
|
293
|
+
// For simple names without parentheses:
|
|
294
|
+
// - Append () ONLY if the entity is a function/hook (detected above)
|
|
295
|
+
// - Don't append () for object/namespace mocks like "supabase"
|
|
296
|
+
if (mockNameIsCallSignature || mockName.includes('(')) {
|
|
297
|
+
dataKey = mockName;
|
|
298
|
+
}
|
|
299
|
+
else if (entityIsFunction) {
|
|
300
|
+
// Entity is a function/hook - append () to match call signature format
|
|
301
|
+
dataKey = `${mockName}()`;
|
|
302
|
+
}
|
|
303
|
+
else {
|
|
304
|
+
// Entity is an object/namespace - use bare name as key
|
|
305
|
+
dataKey = mockName;
|
|
306
|
+
}
|
|
307
|
+
// Helper to wrap key in appropriate quotes for computed property access
|
|
308
|
+
// Use single quotes when key contains double quotes to avoid syntax errors
|
|
309
|
+
const quotePropertyKey = (key) => {
|
|
310
|
+
const escaped = key.replace(/\n/g, '\\n');
|
|
311
|
+
if (escaped.includes('"')) {
|
|
312
|
+
// Use single quotes, escaping any single quotes in the key
|
|
313
|
+
return `['${escaped.replace(/'/g, "\\'")}']`;
|
|
314
|
+
}
|
|
315
|
+
return `["${escaped}"]`;
|
|
316
|
+
};
|
|
213
317
|
// Check if the return value schema only contains function type markers
|
|
214
318
|
// (e.g., "validateInputs()": "function") without actual return data
|
|
215
319
|
// (no functionCallReturnValue entries)
|
|
@@ -232,6 +336,8 @@ export default function constructMockCode(mockName, dependencySchemas, entityTyp
|
|
|
232
336
|
// Count the number of arguments from signature schema
|
|
233
337
|
const argCount = Object.keys(signatureSchema).filter((key) => key.startsWith('signature[')).length;
|
|
234
338
|
const args = Array.from({ length: argCount }, (_, i) => `arg${i + 1}`);
|
|
339
|
+
// Always add ...rest to accept extra arguments beyond the signature
|
|
340
|
+
args.push('...rest');
|
|
235
341
|
const argsString = args.join(', ');
|
|
236
342
|
// Generate empty mock function
|
|
237
343
|
return `function ${mockName}(${argsString}) {
|
|
@@ -250,7 +356,33 @@ export default function constructMockCode(mockName, dependencySchemas, entityTyp
|
|
|
250
356
|
!hasMeaningfulReturnData(relevantReturnValueSchema)) {
|
|
251
357
|
const argCount = Object.keys(signatureSchema).filter((key) => key.startsWith('signature[')).length;
|
|
252
358
|
const args = Array.from({ length: argCount }, (_, i) => `arg${i + 1}`);
|
|
359
|
+
// Always add ...rest to accept extra arguments beyond the signature
|
|
360
|
+
args.push('...rest');
|
|
253
361
|
const argsString = args.join(', ');
|
|
362
|
+
// Check for Higher-Order Component (HOC) pattern:
|
|
363
|
+
// - First argument is a function (component) or unknown (couldn't trace type)
|
|
364
|
+
// - Returns a function
|
|
365
|
+
// HOCs like memo, forwardRef, createContext should return their first argument
|
|
366
|
+
//
|
|
367
|
+
// The return value key can be either:
|
|
368
|
+
// - 'memo()' (clean format)
|
|
369
|
+
// - 'memo(({ value, width }: Props) => { ... })' (full component code format)
|
|
370
|
+
const firstArgIsFunctionOrUnknown = signatureSchema['signature[0]'] === 'function' ||
|
|
371
|
+
signatureSchema['signature[0]'] === 'unknown';
|
|
372
|
+
const returnsFunction = relevantReturnValueSchema
|
|
373
|
+
? Object.entries(relevantReturnValueSchema).some(([key, value]) => {
|
|
374
|
+
// Check if key represents a function call that returns a function
|
|
375
|
+
// Key should start with the mock name, contain '(', end with ')', and have value 'function'
|
|
376
|
+
const isFunctionCall = key.startsWith(mockName + '(') && key.endsWith(')');
|
|
377
|
+
return isFunctionCall && value === 'function';
|
|
378
|
+
})
|
|
379
|
+
: false;
|
|
380
|
+
if (firstArgIsFunctionOrUnknown && returnsFunction) {
|
|
381
|
+
// HOC pattern detected - return the first argument
|
|
382
|
+
return `function ${mockName}(${argsString}) {
|
|
383
|
+
return arg1;
|
|
384
|
+
}`;
|
|
385
|
+
}
|
|
254
386
|
// Generate empty mock function
|
|
255
387
|
return `function ${mockName}(${argsString}) {
|
|
256
388
|
// Empty mock - original function mocked out
|
|
@@ -287,20 +419,19 @@ export default function constructMockCode(mockName, dependencySchemas, entityTyp
|
|
|
287
419
|
// Strip type parameters like <typeof loader> from function names
|
|
288
420
|
// so "useLoaderData<typeof loader>()" becomes "useLoaderData()"
|
|
289
421
|
name = cleanOutTypes(name);
|
|
290
|
-
// For
|
|
291
|
-
// This
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
//
|
|
295
|
-
|
|
296
|
-
|
|
422
|
+
// For root data access, use the dataKey (original call signature or canonical key)
|
|
423
|
+
// This preserves the original call signature for LLM clarity
|
|
424
|
+
if (isRootAccess) {
|
|
425
|
+
// For call signature format, use the original mockName as the data key
|
|
426
|
+
// e.g., scenarios().data()?.["useFetcher<User>()"]
|
|
427
|
+
// e.g., scenarios().data()?.["db.select(usersQuery)"]
|
|
428
|
+
return `?.${quotePropertyKey(dataKey)}`;
|
|
297
429
|
}
|
|
298
430
|
// Only use unquoted array access syntax for pure array indices like [0], [1]
|
|
299
|
-
|
|
300
|
-
if (name.match(/^\[\d+\]$/) && !name.includes(' <- ')) {
|
|
431
|
+
if (name.match(/^\[\d+\]$/)) {
|
|
301
432
|
return `?.${name}`;
|
|
302
433
|
}
|
|
303
|
-
return
|
|
434
|
+
return `?.${quotePropertyKey(name)}`;
|
|
304
435
|
};
|
|
305
436
|
const constructDataPaths = () => {
|
|
306
437
|
// For structural elements, return modified base paths for children
|
|
@@ -348,7 +479,17 @@ export default function constructMockCode(mockName, dependencySchemas, entityTyp
|
|
|
348
479
|
};
|
|
349
480
|
const constructContent = (dataPaths) => {
|
|
350
481
|
const { name, args, nested, isArray, isGenericArray, returnsFunctionArgs, returnsFunctionArray, isAsyncFunction, hasNoReturnData, } = returnValue;
|
|
351
|
-
|
|
482
|
+
// When an array has differentiated indices ([0], [1], etc.), filter out any
|
|
483
|
+
// non-index items from nested. These non-index items come from generic [] paths
|
|
484
|
+
// like [].filter or [].sort, which describe element properties, not array elements.
|
|
485
|
+
// Including them would generate invalid syntax like "sort: ..." inside an array literal.
|
|
486
|
+
const hasDifferentiatedIndices = isArray &&
|
|
487
|
+
nested &&
|
|
488
|
+
nested.some((n) => n.name.match(/^\[\d+\]$/) && n.name !== '[0]');
|
|
489
|
+
const filteredNested = hasDifferentiatedIndices && nested
|
|
490
|
+
? nested.filter((n) => n.name.match(/^\[\d+\]$/))
|
|
491
|
+
: nested;
|
|
492
|
+
const nestedContent = (filteredNested ?? []).map((nestedItem) => {
|
|
352
493
|
const nestedContent = constructReturnValueString(nestedItem, dataPaths);
|
|
353
494
|
return nestedContent;
|
|
354
495
|
});
|
|
@@ -422,52 +563,110 @@ export default function constructMockCode(mockName, dependencySchemas, entityTyp
|
|
|
422
563
|
(!returnValue.isStructural || isStructuralArrayElementWithNested)) {
|
|
423
564
|
levelContentItems.push(...dataPaths.map((path) => `...${path}`));
|
|
424
565
|
}
|
|
425
|
-
|
|
566
|
+
// Filter out nested content that would be invalid as object properties
|
|
567
|
+
// (e.g., bare arrow functions like "() => {...}" without a property name)
|
|
568
|
+
// Only apply this filter when building object content, not array content.
|
|
569
|
+
// Bare arrow functions ARE valid as array elements (like [0] = {...}, [1] = () => {...})
|
|
570
|
+
// Check both isArray (item IS an array) and returnsFunctionArray (item returns an array)
|
|
571
|
+
const inArrayContext = isArray || returnsFunctionArray;
|
|
572
|
+
const validNestedContent = nestedContent.filter((content) => {
|
|
573
|
+
if (!content)
|
|
574
|
+
return false;
|
|
575
|
+
// Only filter bare arrow functions when NOT in array context
|
|
576
|
+
// In arrays, bare arrow functions are valid elements
|
|
577
|
+
if (!inArrayContext && content.match(/^\s*\([^)]*\)\s*=>/)) {
|
|
578
|
+
return false;
|
|
579
|
+
}
|
|
580
|
+
return true;
|
|
581
|
+
});
|
|
582
|
+
levelContentItems.push(...validNestedContent);
|
|
426
583
|
let levelContents = levelContentItems.filter(Boolean).join(',\n');
|
|
427
584
|
if (returnsFunctionArgs) {
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
585
|
+
// When returnsFunctionArgs is empty [] OR has a single literal string argument,
|
|
586
|
+
// the function returns a callable function (e.g., getTranslate() returns t,
|
|
587
|
+
// where t('key') looks up translations)
|
|
588
|
+
// Generate a dispatch function that looks up keys based on the argument
|
|
589
|
+
//
|
|
590
|
+
// Detect translation-like pattern:
|
|
591
|
+
// - Data path ends with ["('some.literal')"] - a literal string key
|
|
592
|
+
// - This means the mock data has keys like "('common.surveys')": "Surveys"
|
|
593
|
+
// - Exclude ["()"] which is an empty function call (not a translation pattern)
|
|
594
|
+
const dataPath = dataPaths[0];
|
|
595
|
+
// Pattern matches ?.["('...')"] at end of path, but NOT ?.["()"] (empty args)
|
|
596
|
+
const literalKeyPattern = dataPath?.match(/\?\.\["\('.+'\)"\]$/);
|
|
597
|
+
if (!returnsFunctionArray &&
|
|
598
|
+
dataPaths.length === 1 &&
|
|
599
|
+
literalKeyPattern // Only dispatch when there's a literal key pattern
|
|
600
|
+
) {
|
|
601
|
+
// Function returns a function - generate dispatch function
|
|
602
|
+
// Strip the literal key from the path and use dynamic lookup
|
|
603
|
+
const dataPathBase = literalKeyPattern
|
|
604
|
+
? dataPath.replace(/\?\.\["\('.+'\)"\]$/, '')
|
|
605
|
+
: dataPath;
|
|
606
|
+
const funcContents = `return ${dataPathBase}?.[\`('\${arg1}')\`]`;
|
|
607
|
+
levelContents = `(arg1) => {\n${indent(funcContents)}\n}`;
|
|
608
|
+
if (!isArray) {
|
|
609
|
+
return levelContents;
|
|
447
610
|
}
|
|
448
611
|
}
|
|
449
612
|
else {
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
613
|
+
const argsString = returnsFunctionArgs
|
|
614
|
+
.map((_, index) => `arg${index + 1}`)
|
|
615
|
+
.join(', ');
|
|
616
|
+
let funcContents = '';
|
|
617
|
+
if (returnsFunctionArray) {
|
|
618
|
+
if (hasNoReturnData) {
|
|
456
619
|
// Function has no return data (only signatures) - return empty array
|
|
457
620
|
funcContents = 'return []';
|
|
458
621
|
}
|
|
459
|
-
else {
|
|
460
|
-
//
|
|
622
|
+
else if (levelContents.length === 0 && dataPaths.length === 1) {
|
|
623
|
+
// When returning an array with no nested content, return the data path directly
|
|
624
|
+
// (the data path points to the array in scenario data)
|
|
461
625
|
funcContents = `return ${dataPaths[0]}`;
|
|
462
626
|
}
|
|
627
|
+
else if (levelContents.length === 0) {
|
|
628
|
+
funcContents = 'return []';
|
|
629
|
+
}
|
|
630
|
+
else {
|
|
631
|
+
funcContents = `return [\n${indent(levelContents)}\n]`;
|
|
632
|
+
}
|
|
463
633
|
}
|
|
464
634
|
else {
|
|
465
|
-
|
|
635
|
+
// Check if function has no actual return data (only signatures)
|
|
636
|
+
const hasNestedItems = nested && nested.length > 0;
|
|
637
|
+
const hasActualNestedContent = nestedContent.filter(Boolean).length > 0;
|
|
638
|
+
if (levelContentItems.length === 1 && dataPaths.length === 1) {
|
|
639
|
+
if (hasNoReturnData ||
|
|
640
|
+
(hasNestedItems && !hasActualNestedContent)) {
|
|
641
|
+
// Function has no return data (only signatures) - return empty array
|
|
642
|
+
funcContents = 'return []';
|
|
643
|
+
}
|
|
644
|
+
else {
|
|
645
|
+
// Has return data - return data path
|
|
646
|
+
funcContents = `return ${dataPaths[0]}`;
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
else {
|
|
650
|
+
funcContents = `return {\n${indent(levelContents)}\n}`;
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
levelContents = `(${argsString}) => {\n${indent(funcContents)}\n}`;
|
|
654
|
+
if (!isArray) {
|
|
655
|
+
return levelContents;
|
|
466
656
|
}
|
|
467
657
|
}
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
658
|
+
// For generic arrays of functions WITH nested properties (e.g., functionCallReturnValue[] = "function"
|
|
659
|
+
// with nested .filter, .sort, etc.), the levelContents would be a bare arrow function "() => {...}"
|
|
660
|
+
// that wraps object content. Using this in a .map(({...})) creates invalid syntax like "({ () => {...} })".
|
|
661
|
+
// When isGenericArray is true AND there are nested properties, we're accessing data from the elements,
|
|
662
|
+
// not calling them - so skip the function wrapping.
|
|
663
|
+
// But if there are NO nested properties, keep the wrapper because callers may want to call the elements.
|
|
664
|
+
const hasNonStructuralNestedItems = nested &&
|
|
665
|
+
nested.length > 0 &&
|
|
666
|
+
nested.some((n) => !n.name.match(/^\[\d*\]$/));
|
|
667
|
+
if (isGenericArray && hasNonStructuralNestedItems) {
|
|
668
|
+
// Skip the arrow function wrapper - just use the nested content directly
|
|
669
|
+
levelContents = levelContentItems.filter(Boolean).join(',\n');
|
|
471
670
|
}
|
|
472
671
|
}
|
|
473
672
|
// Check if all nested items are array prototype methods
|
|
@@ -499,20 +698,343 @@ export default function constructMockCode(mockName, dependencySchemas, entityTyp
|
|
|
499
698
|
// When GENERIC array (using []) has nested content (like functions that need wrapping),
|
|
500
699
|
// use .map() to transform ALL elements instead of just creating [0]
|
|
501
700
|
// For DIFFERENTIATED arrays (using [0], [1], etc.), keep the static array structure
|
|
701
|
+
//
|
|
702
|
+
// IMPORTANT: If the nested content contains differentiated indices like [0], [1],
|
|
703
|
+
// we MUST use static array pattern, not .map(). The presence of differentiated
|
|
704
|
+
// indices means the array elements have different types/structures, so .map()
|
|
705
|
+
// would generate invalid code trying to treat them uniformly.
|
|
706
|
+
const hasDifferentiatedIndices = nested &&
|
|
707
|
+
nested.some((n) => n.name.match(/^\[\d+\]$/) && n.name !== '[0]');
|
|
502
708
|
if (isGenericArray &&
|
|
503
709
|
nestedContent.length > 0 &&
|
|
504
|
-
dataPaths.length > 0
|
|
710
|
+
dataPaths.length > 0 &&
|
|
711
|
+
!hasDifferentiatedIndices) {
|
|
505
712
|
// Get the array base path (without the [0])
|
|
506
713
|
const arrayBasePath = dataPaths[0].replace(/\?\.\[0\]$/, '');
|
|
507
714
|
// Replace [0] references with [__idx__] in level contents
|
|
508
|
-
|
|
715
|
+
let mappedContents = levelContents.replace(/\?\.\[0\]/g, '?.[__idx__]');
|
|
509
716
|
// levelContents may already be wrapped in {...} from structural [0] element,
|
|
510
717
|
// so check if we need to add the wrapper or not
|
|
511
718
|
const needsWrapper = !mappedContents.trim().startsWith('{');
|
|
719
|
+
// Helper to check if a position is inside a string literal
|
|
720
|
+
// Returns the end position of the string if inside one, -1 otherwise
|
|
721
|
+
// Defined here so it's accessible in both needsWrapper branches
|
|
722
|
+
const skipStringLiteral = (content, pos) => {
|
|
723
|
+
const char = content[pos];
|
|
724
|
+
if (char !== '"' && char !== "'" && char !== '`')
|
|
725
|
+
return -1;
|
|
726
|
+
// Find the matching closing quote
|
|
727
|
+
let j = pos + 1;
|
|
728
|
+
while (j < content.length) {
|
|
729
|
+
if (content[j] === '\\') {
|
|
730
|
+
j += 2; // Skip escaped character
|
|
731
|
+
continue;
|
|
732
|
+
}
|
|
733
|
+
if (content[j] === char) {
|
|
734
|
+
return j + 1; // Return position after closing quote
|
|
735
|
+
}
|
|
736
|
+
j++;
|
|
737
|
+
}
|
|
738
|
+
return content.length; // Unclosed string, skip to end
|
|
739
|
+
};
|
|
740
|
+
// Filter out bare arrow functions which are invalid as object properties.
|
|
741
|
+
// Arrow functions can be multi-line, so we need to match the entire function body, not just the first line.
|
|
742
|
+
// Pattern: starts with "(args) =>", followed by either:
|
|
743
|
+
// - A single-line body: "() => expression"
|
|
744
|
+
// - A multi-line body: "() => { ... }" (with matching braces)
|
|
745
|
+
// IMPORTANT: Only filter BARE arrow functions (without property names).
|
|
746
|
+
// "() => {...}" is invalid, but "get: (arg1) => {...}" is valid.
|
|
747
|
+
// We use a function to properly handle nested braces.
|
|
748
|
+
// Defined here so it's accessible in both needsWrapper branches
|
|
749
|
+
const filterOutArrowFunctions = (content) => {
|
|
750
|
+
const result = [];
|
|
751
|
+
let i = 0;
|
|
752
|
+
while (i < content.length) {
|
|
753
|
+
// Skip over string literals entirely
|
|
754
|
+
const stringEnd = skipStringLiteral(content, i);
|
|
755
|
+
if (stringEnd !== -1) {
|
|
756
|
+
result.push(content.slice(i, stringEnd));
|
|
757
|
+
i = stringEnd;
|
|
758
|
+
continue;
|
|
759
|
+
}
|
|
760
|
+
// Check if we're at the start of an arrow function (with optional leading whitespace)
|
|
761
|
+
const arrowMatch = content
|
|
762
|
+
.slice(i)
|
|
763
|
+
.match(/^(\s*)\([^)]*\)\s*=>\s*/);
|
|
764
|
+
if (arrowMatch) {
|
|
765
|
+
// Check if this is a bare arrow function or a named property with arrow function value
|
|
766
|
+
// Look back to see if there's a "key:" pattern before this position
|
|
767
|
+
const before = content.slice(0, i);
|
|
768
|
+
const beforeTrimmed = before.trim();
|
|
769
|
+
// Valid patterns where arrow function is NOT bare:
|
|
770
|
+
// 1. Property value: "key: (arg) => ..." - ends with ':'
|
|
771
|
+
// 2. Function argument: ".map((arg) => ..." - ends with '('
|
|
772
|
+
// NOTE: We don't include ',' because "{ prop, () => {} }" is invalid
|
|
773
|
+
// (can't distinguish function argument from object property context)
|
|
774
|
+
const isPropertyValue = beforeTrimmed.endsWith(':');
|
|
775
|
+
const isFunctionArg = beforeTrimmed.endsWith('(');
|
|
776
|
+
const hasPropertyName = isPropertyValue || isFunctionArg;
|
|
777
|
+
if (!hasPropertyName) {
|
|
778
|
+
// This is a bare arrow function - filter it out
|
|
779
|
+
// Found arrow function start, need to find its end
|
|
780
|
+
const afterArrow = i + arrowMatch[0].length;
|
|
781
|
+
if (content[afterArrow] === '{') {
|
|
782
|
+
// Multi-line arrow function - find matching closing brace
|
|
783
|
+
// Must respect string literals when counting braces
|
|
784
|
+
let braceCount = 1;
|
|
785
|
+
let j = afterArrow + 1;
|
|
786
|
+
while (j < content.length && braceCount > 0) {
|
|
787
|
+
const strEnd = skipStringLiteral(content, j);
|
|
788
|
+
if (strEnd !== -1) {
|
|
789
|
+
j = strEnd;
|
|
790
|
+
continue;
|
|
791
|
+
}
|
|
792
|
+
if (content[j] === '{')
|
|
793
|
+
braceCount++;
|
|
794
|
+
if (content[j] === '}')
|
|
795
|
+
braceCount--;
|
|
796
|
+
j++;
|
|
797
|
+
}
|
|
798
|
+
// Skip past the arrow function
|
|
799
|
+
i = j;
|
|
800
|
+
// Only skip trailing comma, keep newlines
|
|
801
|
+
while (i < content.length && content[i] === ' ') {
|
|
802
|
+
i++;
|
|
803
|
+
}
|
|
804
|
+
if (content[i] === ',') {
|
|
805
|
+
i++; // Skip the comma after the arrow function
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
else {
|
|
809
|
+
// Single expression arrow function - skip to next comma or newline
|
|
810
|
+
let j = afterArrow;
|
|
811
|
+
while (j < content.length &&
|
|
812
|
+
content[j] !== ',' &&
|
|
813
|
+
content[j] !== '\n') {
|
|
814
|
+
j++;
|
|
815
|
+
}
|
|
816
|
+
i = j;
|
|
817
|
+
if (content[i] === ',')
|
|
818
|
+
i++; // Skip the comma
|
|
819
|
+
}
|
|
820
|
+
continue;
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
// Not a bare arrow function, keep this character
|
|
824
|
+
result.push(content[i]);
|
|
825
|
+
i++;
|
|
826
|
+
}
|
|
827
|
+
return result.join('');
|
|
828
|
+
};
|
|
829
|
+
// Filter out bare object blocks (e.g., "{ ...spread, props }," without a property name)
|
|
830
|
+
// These are invalid in object literal context - you need "key: { ... }" not just "{ ... }"
|
|
831
|
+
// Defined here so it's accessible in both needsWrapper branches
|
|
832
|
+
// The skipFirstBrace parameter allows the else branch to preserve the outer object
|
|
833
|
+
const filterOutBareObjects = (content, skipFirstBrace = false) => {
|
|
834
|
+
const result = [];
|
|
835
|
+
let i = 0;
|
|
836
|
+
let firstBraceSkipped = false;
|
|
837
|
+
while (i < content.length) {
|
|
838
|
+
// Skip over string literals entirely - braces inside strings should not be processed
|
|
839
|
+
const stringEnd = skipStringLiteral(content, i);
|
|
840
|
+
if (stringEnd !== -1) {
|
|
841
|
+
result.push(content.slice(i, stringEnd));
|
|
842
|
+
i = stringEnd;
|
|
843
|
+
continue;
|
|
844
|
+
}
|
|
845
|
+
// Check if we're at a bare object start (newline/comma followed by { without : before it)
|
|
846
|
+
// Look back to see if there's a colon (property assignment) before this brace
|
|
847
|
+
const isStartOfLine = i === 0 ||
|
|
848
|
+
content[i - 1] === '\n' ||
|
|
849
|
+
content.slice(0, i).trim().endsWith(',');
|
|
850
|
+
if (content[i] === '{' && isStartOfLine) {
|
|
851
|
+
// Check if this is actually a bare object (not "key: {")
|
|
852
|
+
const beforeTrimmed = content.slice(0, i).trim();
|
|
853
|
+
const isBareObject = beforeTrimmed.endsWith(',') ||
|
|
854
|
+
beforeTrimmed === '' ||
|
|
855
|
+
beforeTrimmed.endsWith('(');
|
|
856
|
+
if (isBareObject) {
|
|
857
|
+
// If skipFirstBrace is true and this is the first bare brace at position 0,
|
|
858
|
+
// don't filter it - it's the intentional outer object wrapper
|
|
859
|
+
if (skipFirstBrace && !firstBraceSkipped && i === 0) {
|
|
860
|
+
firstBraceSkipped = true;
|
|
861
|
+
result.push(content[i]);
|
|
862
|
+
i++;
|
|
863
|
+
continue;
|
|
864
|
+
}
|
|
865
|
+
// Find matching closing brace, respecting string literals
|
|
866
|
+
let braceCount = 1;
|
|
867
|
+
let j = i + 1;
|
|
868
|
+
while (j < content.length && braceCount > 0) {
|
|
869
|
+
const strEnd = skipStringLiteral(content, j);
|
|
870
|
+
if (strEnd !== -1) {
|
|
871
|
+
j = strEnd;
|
|
872
|
+
continue;
|
|
873
|
+
}
|
|
874
|
+
if (content[j] === '{')
|
|
875
|
+
braceCount++;
|
|
876
|
+
if (content[j] === '}')
|
|
877
|
+
braceCount--;
|
|
878
|
+
j++;
|
|
879
|
+
}
|
|
880
|
+
// Skip past the object
|
|
881
|
+
i = j;
|
|
882
|
+
// Skip trailing comma
|
|
883
|
+
while (i < content.length && content[i] === ' ') {
|
|
884
|
+
i++;
|
|
885
|
+
}
|
|
886
|
+
if (content[i] === ',') {
|
|
887
|
+
i++;
|
|
888
|
+
}
|
|
889
|
+
continue;
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
result.push(content[i]);
|
|
893
|
+
i++;
|
|
894
|
+
}
|
|
895
|
+
return result.join('');
|
|
896
|
+
};
|
|
897
|
+
// Helper to clean up formatting issues after filtering
|
|
898
|
+
const cleanupContent = (content) => {
|
|
899
|
+
return (content
|
|
900
|
+
.replace(/,\s*,/g, ',') // Double commas
|
|
901
|
+
.replace(/,(\s*\n\s*\})/g, '$1') // Trailing comma before closing brace
|
|
902
|
+
.replace(/\{\s*\n\s*,/g, '{\n') // Leading comma after opening brace
|
|
903
|
+
// Remove incomplete .map calls where callback was filtered out
|
|
904
|
+
// Pattern: ".map" followed by newline/whitespace without "(" for args
|
|
905
|
+
.replace(/\?\.map(?=\s*[\n\r,}\]])/g, '')
|
|
906
|
+
.replace(/\.map(?=\s*[\n\r,}\]])/g, '')
|
|
907
|
+
// Clean up orphan })) sequences (from nested filtered map callbacks)
|
|
908
|
+
.replace(/\s*\}\)\)\s*\n\s*\}/g, '\n}')
|
|
909
|
+
.replace(/^\s*\n/gm, '') // Empty lines
|
|
910
|
+
.trim());
|
|
911
|
+
};
|
|
512
912
|
if (needsWrapper) {
|
|
513
|
-
|
|
913
|
+
// Apply filters to remove invalid content
|
|
914
|
+
mappedContents = filterOutArrowFunctions(mappedContents);
|
|
915
|
+
mappedContents = filterOutBareObjects(mappedContents);
|
|
916
|
+
mappedContents = cleanupContent(mappedContents);
|
|
917
|
+
// If mappedContents is empty after filtering, don't generate .map() at all
|
|
918
|
+
// Just use the array path directly with spread or as-is
|
|
919
|
+
// This prevents orphan )) from empty .map() callbacks
|
|
920
|
+
const cleanedForEmptyCheck = mappedContents
|
|
921
|
+
.replace(/\s+/g, '')
|
|
922
|
+
.replace(/,+/g, '');
|
|
923
|
+
if (cleanedForEmptyCheck.length === 0) {
|
|
924
|
+
// Content is empty - just return the array directly
|
|
925
|
+
returnValueContents = arrayBasePath;
|
|
926
|
+
}
|
|
927
|
+
else {
|
|
928
|
+
// Check if mappedContents is just a bare expression (no property names)
|
|
929
|
+
// A bare expression like "scenarios().data()?.["key"]?.[__idx__]," cannot be
|
|
930
|
+
// wrapped in ({ }) because it's not a valid object property.
|
|
931
|
+
// Pattern: content has no ":" that's not inside brackets/parens/strings
|
|
932
|
+
const hasBareExpression = (() => {
|
|
933
|
+
const trimmed = mappedContents.trim().replace(/,\s*$/, ''); // Remove trailing comma
|
|
934
|
+
let depth = 0;
|
|
935
|
+
let inString = false;
|
|
936
|
+
let stringChar = '';
|
|
937
|
+
for (let i = 0; i < trimmed.length; i++) {
|
|
938
|
+
const char = trimmed[i];
|
|
939
|
+
if (inString) {
|
|
940
|
+
if (char === '\\') {
|
|
941
|
+
i++; // Skip escaped char
|
|
942
|
+
continue;
|
|
943
|
+
}
|
|
944
|
+
if (char === stringChar) {
|
|
945
|
+
inString = false;
|
|
946
|
+
}
|
|
947
|
+
continue;
|
|
948
|
+
}
|
|
949
|
+
if (char === '"' || char === "'" || char === '`') {
|
|
950
|
+
inString = true;
|
|
951
|
+
stringChar = char;
|
|
952
|
+
continue;
|
|
953
|
+
}
|
|
954
|
+
if (char === '(' || char === '[' || char === '{') {
|
|
955
|
+
depth++;
|
|
956
|
+
continue;
|
|
957
|
+
}
|
|
958
|
+
if (char === ')' || char === ']' || char === '}') {
|
|
959
|
+
depth--;
|
|
960
|
+
continue;
|
|
961
|
+
}
|
|
962
|
+
// Found a colon at depth 0 = has property name
|
|
963
|
+
if (char === ':' && depth === 0) {
|
|
964
|
+
return false;
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
return true;
|
|
968
|
+
})();
|
|
969
|
+
if (hasBareExpression) {
|
|
970
|
+
// Content is just an expression - return it directly without object wrapper
|
|
971
|
+
const trimmedContent = mappedContents
|
|
972
|
+
.trim()
|
|
973
|
+
.replace(/,\s*$/, '');
|
|
974
|
+
returnValueContents = `${arrayBasePath}?.map((__item__, __idx__) => (\n${indent(trimmedContent)}\n))`;
|
|
975
|
+
}
|
|
976
|
+
else {
|
|
977
|
+
returnValueContents = `${arrayBasePath}?.map((__item__, __idx__) => ({\n${indent(mappedContents)}\n}))`;
|
|
978
|
+
}
|
|
979
|
+
} // Close the empty content check else block
|
|
514
980
|
}
|
|
515
981
|
else {
|
|
982
|
+
// Content already starts with '{'. Check if there are additional properties after the inner object.
|
|
983
|
+
// If so, we need to merge them INTO the object, not leave them outside.
|
|
984
|
+
// Pattern: "{ ...spread, props },\nfilter: ...,\nsort: ..."
|
|
985
|
+
// Should become: "{ ...spread, props, filter: ..., sort: ... }"
|
|
986
|
+
const trimmed = mappedContents.trim();
|
|
987
|
+
// Find first }, at depth 0 that is NOT inside a string literal
|
|
988
|
+
// This prevents splitting keys like ?.["useQuery({ id }, { enabled })"]
|
|
989
|
+
// and also prevents finding }, inside nested arrow functions
|
|
990
|
+
const findBraceCommaOutsideStrings = (content) => {
|
|
991
|
+
let i = 0;
|
|
992
|
+
let depth = 0; // Track brace depth to find the outer object's },
|
|
993
|
+
while (i < content.length - 1) {
|
|
994
|
+
// Skip over string literals
|
|
995
|
+
const strEnd = skipStringLiteral(content, i);
|
|
996
|
+
if (strEnd !== -1) {
|
|
997
|
+
i = strEnd;
|
|
998
|
+
continue;
|
|
999
|
+
}
|
|
1000
|
+
// Track brace depth
|
|
1001
|
+
if (content[i] === '{') {
|
|
1002
|
+
depth++;
|
|
1003
|
+
i++;
|
|
1004
|
+
continue;
|
|
1005
|
+
}
|
|
1006
|
+
// Check for }, pattern at depth 1 (the outer object level)
|
|
1007
|
+
// We're looking for the outer object's closing brace, which is at depth 1
|
|
1008
|
+
// (we started at depth 0, opened { at depth 0 -> 1)
|
|
1009
|
+
if (content[i] === '}') {
|
|
1010
|
+
depth--;
|
|
1011
|
+
if (depth === 0 &&
|
|
1012
|
+
i + 1 < content.length &&
|
|
1013
|
+
content[i + 1] === ',') {
|
|
1014
|
+
return i;
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
i++;
|
|
1018
|
+
}
|
|
1019
|
+
return -1;
|
|
1020
|
+
};
|
|
1021
|
+
const firstBraceEnd = findBraceCommaOutsideStrings(trimmed);
|
|
1022
|
+
if (firstBraceEnd !== -1) {
|
|
1023
|
+
// Found pattern "{ ... }," followed by more content
|
|
1024
|
+
// Extract the inner object and the trailing properties
|
|
1025
|
+
const innerObject = trimmed.slice(0, firstBraceEnd);
|
|
1026
|
+
const trailingContent = trimmed.slice(firstBraceEnd + 2).trim();
|
|
1027
|
+
if (trailingContent) {
|
|
1028
|
+
// Merge trailing properties into the inner object
|
|
1029
|
+
mappedContents = `${innerObject},\n${trailingContent}\n}`;
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
// Even when content starts with {, we need to filter out invalid properties inside
|
|
1033
|
+
// (arrow functions and bare objects that were generated from the schema)
|
|
1034
|
+
// Pass skipFirstBrace=true because the content's outer { is the intentional wrapper
|
|
1035
|
+
mappedContents = filterOutArrowFunctions(mappedContents);
|
|
1036
|
+
mappedContents = filterOutBareObjects(mappedContents, true);
|
|
1037
|
+
mappedContents = cleanupContent(mappedContents);
|
|
516
1038
|
returnValueContents = `${arrayBasePath}?.map((__item__, __idx__) => (\n${indent(mappedContents)}\n))`;
|
|
517
1039
|
}
|
|
518
1040
|
}
|
|
@@ -531,6 +1053,12 @@ export default function constructMockCode(mockName, dependencySchemas, entityTyp
|
|
|
531
1053
|
if (args && args.length > 0) {
|
|
532
1054
|
if (!isValidKey(name))
|
|
533
1055
|
return;
|
|
1056
|
+
// Skip array index patterns like [], [0], [1] when they have args
|
|
1057
|
+
// These represent function calls on array elements, not property keys
|
|
1058
|
+
// e.g., customSizes[].(args) means each array element is callable, not a property named "[]"
|
|
1059
|
+
if (name.match(/^\[\d*\]$/)) {
|
|
1060
|
+
return;
|
|
1061
|
+
}
|
|
534
1062
|
const mostArgs = args.sort((a, b) => b.length - a.length)[0];
|
|
535
1063
|
const argsString = mostArgs
|
|
536
1064
|
.map((_, index) => `arg${index + 1}`)
|
|
@@ -570,8 +1098,19 @@ export default function constructMockCode(mockName, dependencySchemas, entityTyp
|
|
|
570
1098
|
fallbackContent = `return ${returnValueContents}`;
|
|
571
1099
|
}
|
|
572
1100
|
else {
|
|
573
|
-
//
|
|
574
|
-
|
|
1101
|
+
// No explicit fallback paths - return the first literal's value as default
|
|
1102
|
+
// Returning spread of all values is dangerous because if values are primitives (strings),
|
|
1103
|
+
// spreading them creates objects with numeric keys like {0:'a', 1:'b', ...}
|
|
1104
|
+
// which causes "Objects are not valid as React child" errors
|
|
1105
|
+
const firstLiteralValue = literalKeys[0];
|
|
1106
|
+
const firstGroupPaths = argGroups.get(firstLiteralValue);
|
|
1107
|
+
if (firstGroupPaths && firstGroupPaths.length === 1) {
|
|
1108
|
+
fallbackContent = `return ${firstGroupPaths[0]}`;
|
|
1109
|
+
}
|
|
1110
|
+
else {
|
|
1111
|
+
// Multiple paths for first literal - return undefined as safe fallback
|
|
1112
|
+
fallbackContent = `return undefined`;
|
|
1113
|
+
}
|
|
575
1114
|
}
|
|
576
1115
|
const funcContents = conditionalBranches.join('\n') +
|
|
577
1116
|
'\n// Fallback for unmatched arguments\n' +
|
|
@@ -580,7 +1119,18 @@ export default function constructMockCode(mockName, dependencySchemas, entityTyp
|
|
|
580
1119
|
}
|
|
581
1120
|
else {
|
|
582
1121
|
// No argument variants - use existing behavior
|
|
583
|
-
|
|
1122
|
+
// But if there's nested content, we need to include it in the return object
|
|
1123
|
+
// (similar to how argument variant branches handle this at line 1070-1072)
|
|
1124
|
+
const hasNestedContent = validNestedContent.length > 0;
|
|
1125
|
+
let funcReturnContents;
|
|
1126
|
+
if (hasNestedContent && levelContentItems.length > 1) {
|
|
1127
|
+
// Include both spread and nested content in the return
|
|
1128
|
+
funcReturnContents = `{\n${indent(levelContents)}\n}`;
|
|
1129
|
+
}
|
|
1130
|
+
else {
|
|
1131
|
+
funcReturnContents = returnValueContents;
|
|
1132
|
+
}
|
|
1133
|
+
const funcContents = `return ${funcReturnContents}`;
|
|
584
1134
|
content = `${cleanOutTypes(name)}: ${isAsyncFunction ? 'async ' : ''}(${argsString}) => {\n${indent(funcContents)}\n}`;
|
|
585
1135
|
}
|
|
586
1136
|
}
|
|
@@ -589,8 +1139,14 @@ export default function constructMockCode(mockName, dependencySchemas, entityTyp
|
|
|
589
1139
|
return;
|
|
590
1140
|
}
|
|
591
1141
|
else if (name.match(/\[\d*\]/)) {
|
|
1142
|
+
// Numeric array index like [0], [1] - can be used as computed property
|
|
592
1143
|
content = returnValueContents;
|
|
593
1144
|
}
|
|
1145
|
+
else if (name.match(/^\[[a-zA-Z_]\w*\]$/)) {
|
|
1146
|
+
// Variable-based index like [currentItemIndex] - must be quoted string key
|
|
1147
|
+
// Otherwise JavaScript would try to evaluate the variable name
|
|
1148
|
+
content = `"${safeString(name)}": ${returnValueContents}`;
|
|
1149
|
+
}
|
|
594
1150
|
else {
|
|
595
1151
|
content = `${safeString(name)}: ${returnValueContents}`;
|
|
596
1152
|
}
|
|
@@ -653,8 +1209,8 @@ export default function constructMockCode(mockName, dependencySchemas, entityTyp
|
|
|
653
1209
|
parts.splice(i, 1);
|
|
654
1210
|
}
|
|
655
1211
|
}
|
|
656
|
-
//
|
|
657
|
-
//
|
|
1212
|
+
// Compare against baseMockName (without generics/args), not the full mockName
|
|
1213
|
+
// e.g., for "useFetcher<User>()", baseMockName is "useFetcher"
|
|
658
1214
|
if (parts[0].split('(')[0] !== baseMockName)
|
|
659
1215
|
continue;
|
|
660
1216
|
// Include paths with functionCallReturnValue OR function-typed paths that need mocking
|
|
@@ -750,6 +1306,16 @@ export default function constructMockCode(mockName, dependencySchemas, entityTyp
|
|
|
750
1306
|
const nextIsArray = !!nextPart?.match(/^\[\d*\]/);
|
|
751
1307
|
const isDifferentiatedArray = !!part?.match(/^\[\d+\]/);
|
|
752
1308
|
const nextIsDifferentiatedArray = !!nextPart?.match(/^\[\d+\]/);
|
|
1309
|
+
// Variable index patterns like [currentItemIndex] or [targetIndex] indicate array access
|
|
1310
|
+
// but don't represent actual data structure - they're markers from variable-based index tracking.
|
|
1311
|
+
// Skip them AND all remaining parts to avoid creating spurious nested structure that breaks array iteration.
|
|
1312
|
+
// The remaining parts (e.g., .missing_attributes) describe properties of array elements, which are
|
|
1313
|
+
// already handled by the generic [] accessor path.
|
|
1314
|
+
const isVariableIndex = !!part?.match(/^\[[a-zA-Z_]\w*\]$/);
|
|
1315
|
+
if (isVariableIndex) {
|
|
1316
|
+
// Break out of the loop entirely - don't process any remaining parts
|
|
1317
|
+
break;
|
|
1318
|
+
}
|
|
753
1319
|
// Find the correct value for the current part being processed
|
|
754
1320
|
let partValue = value; // default to the final value
|
|
755
1321
|
if (isFunctionCallReturnValue(part) && nextIsArray) {
|
|
@@ -841,7 +1407,35 @@ export default function constructMockCode(mockName, dependencySchemas, entityTyp
|
|
|
841
1407
|
}
|
|
842
1408
|
}
|
|
843
1409
|
else {
|
|
844
|
-
|
|
1410
|
+
// Before setting returnsFunctionArgs on the parent (for generic [] = function),
|
|
1411
|
+
// check if there are specific array indices (like [0], [1]) that are NOT functions.
|
|
1412
|
+
// If so, don't set returnsFunctionArgs because those specific indices take precedence.
|
|
1413
|
+
// This prevents adding ["()"] to paths like [0] when [0] is 'unknown' but [] is 'function'.
|
|
1414
|
+
//
|
|
1415
|
+
// Use parts.slice(0, i + 1) to get the current path INCLUDING functionCallReturnValue.
|
|
1416
|
+
// For example, if parts = ['useAtom()','functionCallReturnValue','[]']
|
|
1417
|
+
// and i = 1, we want to check 'useAtom().functionCallReturnValue[0]' etc.
|
|
1418
|
+
const arrayContainerPath = joinParenthesesAndArrays(parts.slice(0, i + 1));
|
|
1419
|
+
const hasNonFunctionSpecificIndices = Object.entries(relevantReturnValueSchema).some(([k, v]) => {
|
|
1420
|
+
// Look for paths like "arrayContainerPath[0]", "arrayContainerPath[1]" etc.
|
|
1421
|
+
const indexMatch = k.match(new RegExp(`^${arrayContainerPath.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\[(\\d+)\\]$`));
|
|
1422
|
+
// If found and it's NOT a function type, we have a conflict
|
|
1423
|
+
return (indexMatch &&
|
|
1424
|
+
!['function', 'async-function'].includes(v));
|
|
1425
|
+
});
|
|
1426
|
+
// Also check if [] has nested object properties (like [].filter, [].name)
|
|
1427
|
+
// If so, [] items are objects with properties, not pure functions to be called
|
|
1428
|
+
// This handles cases where the schema shows [].filter = object but doesn't
|
|
1429
|
+
// have explicit [0] entries
|
|
1430
|
+
const genericArrayPath = `${arrayContainerPath}[]`;
|
|
1431
|
+
const hasNestedProperties = Object.keys(relevantReturnValueSchema).some((k) => {
|
|
1432
|
+
// Check for paths like "arrayContainerPath[].propertyName" (not [].())
|
|
1433
|
+
return (k.startsWith(genericArrayPath + '.') &&
|
|
1434
|
+
!k.startsWith(genericArrayPath + '.('));
|
|
1435
|
+
});
|
|
1436
|
+
if (!hasNonFunctionSpecificIndices && !hasNestedProperties) {
|
|
1437
|
+
returnValueSection.returnsFunctionArgs = [];
|
|
1438
|
+
}
|
|
845
1439
|
}
|
|
846
1440
|
}
|
|
847
1441
|
}
|
|
@@ -862,7 +1456,8 @@ export default function constructMockCode(mockName, dependencySchemas, entityTyp
|
|
|
862
1456
|
}
|
|
863
1457
|
// If the next part is an object with nested content, continue processing
|
|
864
1458
|
// This handles paths like functionCallReturnValue.selectedOptions.elementOptions[]
|
|
865
|
-
|
|
1459
|
+
// Also handles union types like 'array | undefined' or 'object | undefined'
|
|
1460
|
+
if (nextValue?.includes('object') || nextValue?.includes('array')) {
|
|
866
1461
|
continue;
|
|
867
1462
|
}
|
|
868
1463
|
}
|
|
@@ -992,7 +1587,12 @@ export default function constructMockCode(mockName, dependencySchemas, entityTyp
|
|
|
992
1587
|
relevantPart.isArray = true;
|
|
993
1588
|
relevantPart.isGenericArray = true;
|
|
994
1589
|
}
|
|
995
|
-
if
|
|
1590
|
+
// Check if there are remaining parts after functionCallReturnValue that need processing
|
|
1591
|
+
// (e.g., data properties like useQuery().functionCallReturnValue.data)
|
|
1592
|
+
const hasRemainingPartsAfterReturnValue = nextPart &&
|
|
1593
|
+
(isFunctionCallReturnValue(nextPart) ||
|
|
1594
|
+
(isFunctionCallReturnValue(parts[i]) && i < parts.length - 1));
|
|
1595
|
+
if (!hasNestedFunction && !hasRemainingPartsAfterReturnValue) {
|
|
996
1596
|
// Before breaking, check if this function returns an array
|
|
997
1597
|
// by looking for a functionCallReturnValue: 'array' entry in the schema
|
|
998
1598
|
if (relevantPart && part.endsWith(')')) {
|
|
@@ -1020,6 +1620,7 @@ export default function constructMockCode(mockName, dependencySchemas, entityTyp
|
|
|
1020
1620
|
const contents = constructReturnValueString(returnValueParts);
|
|
1021
1621
|
if (mockNameParts.length > 1) {
|
|
1022
1622
|
const originalLib = `${mockNameParts[0]}__cyOriginal`;
|
|
1623
|
+
const skipOriginalSpread = options?.skipOriginalSpread;
|
|
1023
1624
|
const subPart = (parts, originalLib) => {
|
|
1024
1625
|
const part = parts.shift();
|
|
1025
1626
|
if (!isValidKey(part))
|
|
@@ -1027,7 +1628,9 @@ export default function constructMockCode(mockName, dependencySchemas, entityTyp
|
|
|
1027
1628
|
const isLast = parts.length === 0;
|
|
1028
1629
|
const partContents = isLast
|
|
1029
1630
|
? contents
|
|
1030
|
-
:
|
|
1631
|
+
: skipOriginalSpread
|
|
1632
|
+
? subPart(parts, originalLib)
|
|
1633
|
+
: `...${originalLib}.${part},\n${subPart(parts, originalLib)}`;
|
|
1031
1634
|
let code = `${part}: {\n${indent(partContents)}\n}`;
|
|
1032
1635
|
if (part.includes('(') || (isFunction && isLast)) {
|
|
1033
1636
|
const args = funcArgs(part)
|
|
@@ -1037,26 +1640,30 @@ export default function constructMockCode(mockName, dependencySchemas, entityTyp
|
|
|
1037
1640
|
}
|
|
1038
1641
|
return code;
|
|
1039
1642
|
};
|
|
1040
|
-
const returnParts =
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1643
|
+
const returnParts = skipOriginalSpread
|
|
1644
|
+
? [subPart(mockNameParts.slice(1), originalLib)]
|
|
1645
|
+
: [
|
|
1646
|
+
`...${mockNameParts[0]}__cyOriginal`,
|
|
1647
|
+
subPart(mockNameParts.slice(1), originalLib),
|
|
1648
|
+
];
|
|
1649
|
+
return `const ${mockNameParts[0]} = {\n${indent(returnParts.filter(Boolean).join(',\n'))}\n};`;
|
|
1045
1650
|
}
|
|
1046
1651
|
else if (isFunction) {
|
|
1047
1652
|
// For headers() and cookies() from next/headers, add common iterator methods
|
|
1048
1653
|
// These are needed when the mock is passed to functions that use .entries(), .keys(), etc.
|
|
1049
1654
|
// (e.g., Object.fromEntries(headers.entries()) in buildLegacyHeaders)
|
|
1050
|
-
const needsIteratorMethods =
|
|
1655
|
+
const needsIteratorMethods = baseMockName === 'headers' || baseMockName === 'cookies';
|
|
1051
1656
|
let enhancedContents = contents;
|
|
1052
1657
|
if (needsIteratorMethods && contents.trim().startsWith('{')) {
|
|
1053
1658
|
// Add iterator methods that operate on the scenario data
|
|
1659
|
+
// Use the dataKey (original call signature or canonical key)
|
|
1660
|
+
const quotedDataKey = quotePropertyKey(dataKey);
|
|
1054
1661
|
const iteratorMethods = `,
|
|
1055
|
-
entries: () => Object.entries(scenarios().data()
|
|
1056
|
-
keys: () => Object.keys(scenarios().data()
|
|
1057
|
-
values: () => Object.values(scenarios().data()
|
|
1058
|
-
forEach: (fn) => Object.entries(scenarios().data()
|
|
1059
|
-
has: (key) => Object.prototype.hasOwnProperty.call(scenarios().data()
|
|
1662
|
+
entries: () => Object.entries(scenarios().data()?.${quotedDataKey} || {}),
|
|
1663
|
+
keys: () => Object.keys(scenarios().data()?.${quotedDataKey} || {}),
|
|
1664
|
+
values: () => Object.values(scenarios().data()?.${quotedDataKey} || {}),
|
|
1665
|
+
forEach: (fn) => Object.entries(scenarios().data()?.${quotedDataKey} || {}).forEach(([k, v]) => fn(v, k)),
|
|
1666
|
+
has: (key) => Object.prototype.hasOwnProperty.call(scenarios().data()?.${quotedDataKey} || {}, key)`;
|
|
1060
1667
|
// Insert before the closing brace (handle trailing whitespace)
|
|
1061
1668
|
enhancedContents = contents.replace(/\}\s*$/, iteratorMethods + '\n}');
|
|
1062
1669
|
}
|
|
@@ -1066,36 +1673,107 @@ export default function constructMockCode(mockName, dependencySchemas, entityTyp
|
|
|
1066
1673
|
// `new ClassName("arg")` wouldn't create the expected instance.
|
|
1067
1674
|
// For Error subclasses (detected by name ending in "Error"), extend Error for proper error handling.
|
|
1068
1675
|
if (entityType === 'class') {
|
|
1069
|
-
const isErrorSubclass =
|
|
1070
|
-
const baseClass = isErrorSubclass ? 'Error' : 'Object';
|
|
1676
|
+
const isErrorSubclass = baseMockName.endsWith('Error');
|
|
1071
1677
|
const superCall = isErrorSubclass ? 'super(message);' : '';
|
|
1072
1678
|
const nameAssignment = isErrorSubclass
|
|
1073
|
-
? `this.name = '${
|
|
1679
|
+
? `this.name = '${baseMockName}';`
|
|
1074
1680
|
: '';
|
|
1075
|
-
|
|
1681
|
+
// Use the safe function name for the class definition
|
|
1682
|
+
const className = mockNameIsCallSignature
|
|
1683
|
+
? derivedFunctionName
|
|
1684
|
+
: baseMockName;
|
|
1685
|
+
return `class ${className}${isErrorSubclass ? ' extends Error' : ''} {
|
|
1076
1686
|
constructor(message) {
|
|
1077
1687
|
${superCall}
|
|
1078
1688
|
${nameAssignment}
|
|
1079
|
-
Object.assign(this, scenarios().data()
|
|
1689
|
+
Object.assign(this, scenarios().data()?.${quotePropertyKey(dataKey)} || {});
|
|
1080
1690
|
}
|
|
1081
1691
|
}`;
|
|
1082
1692
|
}
|
|
1083
|
-
//
|
|
1084
|
-
//
|
|
1085
|
-
//
|
|
1086
|
-
//
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1693
|
+
// Generate safe function name:
|
|
1694
|
+
// 1. For call signatures: use derivedFunctionName
|
|
1695
|
+
// e.g., "useFetcher<User>()" becomes "useFetcher_User"
|
|
1696
|
+
// e.g., "db.select(usersQuery)" becomes "db_select_usersQuery"
|
|
1697
|
+
// 2. With uniqueFunctionSuffix option: append suffix for unique naming
|
|
1698
|
+
// e.g., baseMockName = "useFetcher", suffix = "entityDiffFetcher" -> "useFetcher_entityDiffFetcher"
|
|
1699
|
+
// 3. EXCEPTION: When keepOriginalFunctionName is true (for single-call cases), use the base name
|
|
1700
|
+
let safeFunctionName;
|
|
1701
|
+
if (options?.keepOriginalFunctionName) {
|
|
1702
|
+
safeFunctionName = baseMockName;
|
|
1703
|
+
}
|
|
1704
|
+
else if (options?.uniqueFunctionSuffix) {
|
|
1705
|
+
safeFunctionName = `${baseMockName}_${options.uniqueFunctionSuffix}`;
|
|
1706
|
+
}
|
|
1707
|
+
else if (mockNameIsCallSignature && derivedFunctionName) {
|
|
1708
|
+
safeFunctionName = derivedFunctionName;
|
|
1709
|
+
}
|
|
1710
|
+
else {
|
|
1711
|
+
safeFunctionName = baseMockName;
|
|
1712
|
+
}
|
|
1713
|
+
// Check if this function returns a function (detected by double-call pattern: mockName(args)())
|
|
1714
|
+
// This happens when the schema has keys like "wrapThrows(() => JSON.parse(savedFilters))()"
|
|
1715
|
+
// where the function call is immediately followed by another call.
|
|
1716
|
+
// Example usage: const result = wrapThrows(() => JSON.parse(x))(); // double call
|
|
1717
|
+
const isHigherOrderFunction = Object.keys(relevantReturnValueSchema ?? {}).some((key) => {
|
|
1718
|
+
if (!key.startsWith(baseMockName))
|
|
1719
|
+
return false;
|
|
1720
|
+
// Find the first ( after baseMockName (the start of the function call)
|
|
1721
|
+
const firstOpenParen = key.indexOf('(', baseMockName.length);
|
|
1722
|
+
if (firstOpenParen === -1)
|
|
1723
|
+
return false;
|
|
1724
|
+
// Skip if the ( is not immediately after the mock name
|
|
1725
|
+
// (there might be type params like func<T>() - handle by checking for < or ()
|
|
1726
|
+
const between = key.slice(baseMockName.length, firstOpenParen);
|
|
1727
|
+
if (between.length > 0 && !between.startsWith('<'))
|
|
1728
|
+
return false;
|
|
1729
|
+
// Find the matching ) for the first ( using depth counting
|
|
1730
|
+
let depth = 1;
|
|
1731
|
+
let i = firstOpenParen + 1;
|
|
1732
|
+
while (i < key.length && depth > 0) {
|
|
1733
|
+
if (key[i] === '(')
|
|
1734
|
+
depth++;
|
|
1735
|
+
if (key[i] === ')')
|
|
1736
|
+
depth--;
|
|
1737
|
+
i++;
|
|
1738
|
+
}
|
|
1739
|
+
if (depth !== 0)
|
|
1740
|
+
return false; // Unbalanced parentheses
|
|
1741
|
+
// Now i points just after the matching )
|
|
1742
|
+
// Check if there's another ( immediately (indicating double call)
|
|
1743
|
+
const remaining = key.slice(i);
|
|
1744
|
+
if (remaining.startsWith('('))
|
|
1745
|
+
return true;
|
|
1746
|
+
return false;
|
|
1747
|
+
});
|
|
1748
|
+
// Use ...args to accept any number of arguments - prevents TypeScript errors
|
|
1749
|
+
// like "Expected 0 arguments, but got X" when caller passes arguments
|
|
1750
|
+
// For higher-order functions, wrap the return in an arrow function
|
|
1751
|
+
// so that mockFunc(arg)() works correctly (outer call returns a function, inner call gets the data)
|
|
1752
|
+
const returnValue = isHigherOrderFunction
|
|
1753
|
+
? `() => (${enhancedContents})`
|
|
1754
|
+
: enhancedContents;
|
|
1755
|
+
// Inline the return value directly in the function to avoid module-level const
|
|
1756
|
+
// that would be evaluated before scenario context is ready
|
|
1757
|
+
return `${isRootAsyncFunction ? 'async ' : ''}function ${safeFunctionName}(...args) {\n${indent(`return ${returnValue};`)}\n}`;
|
|
1091
1758
|
}
|
|
1092
1759
|
else {
|
|
1093
|
-
//
|
|
1094
|
-
//
|
|
1095
|
-
//
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1760
|
+
// Generate safe const name:
|
|
1761
|
+
// 1. For call signatures: use derivedFunctionName
|
|
1762
|
+
// 2. With uniqueFunctionSuffix option: append suffix for unique naming
|
|
1763
|
+
// 3. EXCEPTION: When keepOriginalFunctionName is true (for single-call cases), use the base name
|
|
1764
|
+
let safeName;
|
|
1765
|
+
if (options?.keepOriginalFunctionName) {
|
|
1766
|
+
safeName = baseMockName;
|
|
1767
|
+
}
|
|
1768
|
+
else if (options?.uniqueFunctionSuffix) {
|
|
1769
|
+
safeName = `${baseMockName}_${options.uniqueFunctionSuffix}`;
|
|
1770
|
+
}
|
|
1771
|
+
else if (mockNameIsCallSignature && derivedFunctionName) {
|
|
1772
|
+
safeName = derivedFunctionName;
|
|
1773
|
+
}
|
|
1774
|
+
else {
|
|
1775
|
+
safeName = baseMockName;
|
|
1776
|
+
}
|
|
1099
1777
|
// Get any jsx-component properties that need to be preserved from the original
|
|
1100
1778
|
const jsxProperties = getJsxComponentProperties(mockName, relevantReturnValueSchema);
|
|
1101
1779
|
// If there are jsx-component properties, add them as references to the original
|