@codeyam/codeyam-cli 0.1.0-staging.b8a55ba → 0.1.0-staging.c1c8678
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 +8 -8
- package/analyzer-template/common/execAsync.ts +1 -1
- package/analyzer-template/log.txt +3 -3
- package/analyzer-template/package.json +15 -12
- package/analyzer-template/packages/ai/index.ts +21 -5
- package/analyzer-template/packages/ai/package.json +3 -3
- package/analyzer-template/packages/ai/src/lib/__mocks__/completionCall.ts +122 -0
- package/analyzer-template/packages/ai/src/lib/analyzeScope.ts +226 -24
- package/analyzer-template/packages/ai/src/lib/astScopes/arrayDerivationDetector.ts +199 -0
- package/analyzer-template/packages/ai/src/lib/astScopes/astScopeAnalyzer.ts +183 -10
- package/analyzer-template/packages/ai/src/lib/astScopes/conditionalEffectsExtractor.ts +644 -0
- package/analyzer-template/packages/ai/src/lib/astScopes/methodSemantics.ts +181 -23
- package/analyzer-template/packages/ai/src/lib/astScopes/patterns/forInStatementHandler.ts +10 -17
- package/analyzer-template/packages/ai/src/lib/astScopes/patterns/ifStatementHandler.ts +18 -0
- package/analyzer-template/packages/ai/src/lib/astScopes/patterns/switchStatementHandler.ts +15 -0
- package/analyzer-template/packages/ai/src/lib/astScopes/patterns/variableDeclarationHandler.ts +181 -1
- package/analyzer-template/packages/ai/src/lib/astScopes/processExpression.ts +1229 -30
- package/analyzer-template/packages/ai/src/lib/astScopes/sharedPatterns.ts +28 -0
- package/analyzer-template/packages/ai/src/lib/astScopes/types.ts +265 -6
- package/analyzer-template/packages/ai/src/lib/checkAllAttributes.ts +29 -10
- package/analyzer-template/packages/ai/src/lib/completionCall.ts +216 -36
- package/analyzer-template/packages/ai/src/lib/dataStructure/ScopeDataStructure.ts +1867 -334
- package/analyzer-template/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/JavascriptFrameworkManager.ts +7 -2
- package/analyzer-template/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/MuiManager.ts +296 -35
- package/analyzer-template/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/ReactFrameworkManager.ts +120 -76
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/BatchSchemaProcessor.ts +16 -3
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/ScopeTreeManager.ts +6 -4
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.ts +54 -3
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/cleanNonObjectFunctions.ts +140 -20
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/coerceObjectsToPrimitivesBySchema.ts +70 -0
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/convertDotNotation.ts +140 -14
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/convertNullToUndefinedBySchema.ts +98 -0
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/convertTypeAnnotationsToValues.ts +179 -0
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/deduplicateFunctionSchemas.ts +40 -30
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.ts +393 -90
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/fixNullIdsBySchema.ts +129 -0
- package/analyzer-template/packages/ai/src/lib/dataStructureChunking.ts +174 -0
- package/analyzer-template/packages/ai/src/lib/deepEqual.ts +30 -0
- package/analyzer-template/packages/ai/src/lib/e2eDataTracking.ts +334 -0
- package/analyzer-template/packages/ai/src/lib/extractCriticalDataKeys.ts +120 -0
- package/analyzer-template/packages/ai/src/lib/generateChangesEntityScenarioData.ts +74 -7
- package/analyzer-template/packages/ai/src/lib/generateChangesEntityScenarios.ts +86 -142
- package/analyzer-template/packages/ai/src/lib/generateEntityDataStructure.ts +59 -3
- package/analyzer-template/packages/ai/src/lib/generateEntityScenarioData.ts +1421 -88
- package/analyzer-template/packages/ai/src/lib/generateEntityScenarios.ts +200 -196
- package/analyzer-template/packages/ai/src/lib/generateExecutionFlows.ts +614 -0
- package/analyzer-template/packages/ai/src/lib/generateExecutionFlowsFromConditionalEffects.ts +528 -0
- package/analyzer-template/packages/ai/src/lib/generateExecutionFlowsFromConditionals.ts +2484 -0
- package/analyzer-template/packages/ai/src/lib/generateExecutionFlowsFromJsxUsages.ts +239 -0
- package/analyzer-template/packages/ai/src/lib/guessScenarioDataFromDescription.ts +5 -5
- package/analyzer-template/packages/ai/src/lib/isolateScopes.ts +328 -7
- package/analyzer-template/packages/ai/src/lib/mergeJsonTypeDefinitions.ts +5 -0
- package/analyzer-template/packages/ai/src/lib/mergeStatements.ts +111 -87
- package/analyzer-template/packages/ai/src/lib/promptGenerators/collapseNullableObjects.ts +118 -0
- package/analyzer-template/packages/ai/src/lib/promptGenerators/gatherAttributesMap.ts +10 -7
- package/analyzer-template/packages/ai/src/lib/promptGenerators/generateChangesEntityScenarioDataGenerator.ts +1 -1
- package/analyzer-template/packages/ai/src/lib/promptGenerators/generateChangesEntityScenariosGenerator.ts +32 -142
- package/analyzer-template/packages/ai/src/lib/promptGenerators/generateChunkPrompt.ts +82 -0
- package/analyzer-template/packages/ai/src/lib/promptGenerators/generateCriticalKeysPrompt.ts +103 -0
- package/analyzer-template/packages/ai/src/lib/promptGenerators/generateEntityScenarioDataGenerator.ts +110 -6
- package/analyzer-template/packages/ai/src/lib/promptGenerators/generateEntityScenariosGenerator.ts +14 -89
- package/analyzer-template/packages/ai/src/lib/promptGenerators/generateMissingKeysPrompt.ts +58 -0
- package/analyzer-template/packages/ai/src/lib/promptGenerators/guessNewScenarioDataFromDescriptionGenerator.ts +11 -11
- package/analyzer-template/packages/ai/src/lib/promptGenerators/simplifyKeysForLLM.ts +391 -0
- package/analyzer-template/packages/ai/src/lib/resolvePathToControllable.ts +824 -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 +122 -3
- package/analyzer-template/packages/ai/src/lib/worker/analyzeScopeWorker.ts +114 -2
- package/analyzer-template/packages/analyze/index.ts +2 -0
- package/analyzer-template/packages/analyze/src/lib/FileAnalyzer.ts +79 -59
- package/analyzer-template/packages/analyze/src/lib/ProjectAnalyzer.ts +113 -26
- package/analyzer-template/packages/analyze/src/lib/analysisContext.ts +44 -4
- 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/asts/sourceFiles/getAllDeclaredEntityNodes.ts +19 -0
- package/analyzer-template/packages/analyze/src/lib/asts/sourceFiles/getAllEntityNodes.ts +19 -0
- package/analyzer-template/packages/analyze/src/lib/asts/sourceFiles/getAllExports.ts +11 -0
- package/analyzer-template/packages/analyze/src/lib/asts/sourceFiles/getImportsAnalysis.ts +8 -0
- package/analyzer-template/packages/analyze/src/lib/asts/sourceFiles/getResolvedModule.ts +49 -1
- package/analyzer-template/packages/analyze/src/lib/asts/sourceFiles/getSourceFilesForAllImports.ts +2 -1
- package/analyzer-template/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.ts +466 -270
- package/analyzer-template/packages/analyze/src/lib/files/analyze/analyzeEntities.ts +34 -1
- package/analyzer-template/packages/analyze/src/lib/files/analyze/dependencyResolver.ts +6 -0
- package/analyzer-template/packages/analyze/src/lib/files/analyze/findOrCreateEntity.ts +3 -0
- package/analyzer-template/packages/analyze/src/lib/files/analyze/gatherEntityMap.ts +4 -2
- package/analyzer-template/packages/analyze/src/lib/files/analyze/validateDependencyAnalyses.ts +33 -10
- 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/analyzeRemixRoute.ts +4 -5
- package/analyzer-template/packages/analyze/src/lib/files/enums/steps.ts +1 -1
- package/analyzer-template/packages/analyze/src/lib/files/getImportedExports.ts +14 -12
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/TransformationTracer.ts +1315 -0
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/enrichArrayTypesFromChildSignatures.ts +201 -46
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/enrichUnknownTypesFromSourceEquivalencies.ts +102 -0
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.ts +593 -84
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateChangesScenarios.ts +28 -62
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateDataStructure.ts +377 -84
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateExecutionFlows.ts +264 -0
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateScenarioData.ts +35 -129
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateScenarios.ts +2 -3
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.ts +970 -140
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/mergeValidatedDataStructures.ts +56 -11
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/propagateArrayItemSchemas.ts +474 -0
- package/analyzer-template/packages/analyze/src/lib/files/setImportedExports.ts +2 -1
- package/analyzer-template/packages/analyze/src/lib/index.ts +1 -0
- package/analyzer-template/packages/analyze/src/lib/utils/getFileByPath.ts +19 -0
- 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/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 +3 -3
- 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/uploadFileToS3.ts +8 -1
- package/analyzer-template/packages/database/package.json +1 -1
- package/analyzer-template/packages/database/src/lib/analysisBranchToDb.ts +1 -1
- package/analyzer-template/packages/database/src/lib/analysisToDb.ts +1 -1
- package/analyzer-template/packages/database/src/lib/branchToDb.ts +1 -1
- package/analyzer-template/packages/database/src/lib/commitBranchToDb.ts +1 -1
- package/analyzer-template/packages/database/src/lib/commitToDb.ts +1 -1
- package/analyzer-template/packages/database/src/lib/fileToDb.ts +1 -1
- package/analyzer-template/packages/database/src/lib/kysely/db.ts +14 -1
- package/analyzer-template/packages/database/src/lib/kysely/tables/commitsTable.ts +6 -0
- package/analyzer-template/packages/database/src/lib/kysely/tables/debugReportsTable.ts +17 -1
- package/analyzer-template/packages/database/src/lib/kysely/tables/labsRequestsTable.ts +52 -0
- package/analyzer-template/packages/database/src/lib/loadAnalyses.ts +58 -1
- package/analyzer-template/packages/database/src/lib/loadAnalysis.ts +13 -0
- package/analyzer-template/packages/database/src/lib/loadBranch.ts +16 -1
- package/analyzer-template/packages/database/src/lib/loadCommit.ts +11 -0
- package/analyzer-template/packages/database/src/lib/loadCommits.ts +28 -0
- package/analyzer-template/packages/database/src/lib/loadEntities.ts +26 -3
- package/analyzer-template/packages/database/src/lib/loadEntityBranches.ts +12 -0
- package/analyzer-template/packages/database/src/lib/loadReadyToBeCapturedAnalyses.ts +7 -3
- package/analyzer-template/packages/database/src/lib/projectToDb.ts +1 -1
- package/analyzer-template/packages/database/src/lib/saveFiles.ts +1 -1
- package/analyzer-template/packages/database/src/lib/scenarioToDb.ts +1 -1
- package/analyzer-template/packages/database/src/lib/updateCommitMetadata.ts +7 -14
- package/analyzer-template/packages/database/src/lib/userScenarioToDb.ts +1 -1
- 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/scenarioComponentForServer.ts +114 -0
- package/analyzer-template/packages/github/dist/database/src/lib/analysisBranchToDb.js +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/analysisBranchToDb.js.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/analysisToDb.js +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/analysisToDb.js.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/branchToDb.js +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/branchToDb.js.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/commitBranchToDb.js +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/commitBranchToDb.js.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/commitToDb.js +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/commitToDb.js.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/fileToDb.js +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/fileToDb.js.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/db.d.ts +2 -0
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/db.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/db.js +11 -1
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/db.js.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/analysesTable.d.ts +1 -18
- 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/commitsTable.d.ts +1 -0
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/commitsTable.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/commitsTable.js +3 -0
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/commitsTable.js.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/debugReportsTable.d.ts +17 -1
- 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.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/labsRequestsTable.d.ts +23 -0
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/labsRequestsTable.d.ts.map +1 -0
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/labsRequestsTable.js +35 -0
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/labsRequestsTable.js.map +1 -0
- 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/loadAnalyses.d.ts +2 -0
- package/analyzer-template/packages/github/dist/database/src/lib/loadAnalyses.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/loadAnalyses.js +45 -2
- package/analyzer-template/packages/github/dist/database/src/lib/loadAnalyses.js.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/loadAnalysis.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/loadAnalysis.js +8 -0
- package/analyzer-template/packages/github/dist/database/src/lib/loadAnalysis.js.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/loadBranch.js +11 -1
- package/analyzer-template/packages/github/dist/database/src/lib/loadBranch.js.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/loadCommit.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/loadCommit.js +7 -0
- package/analyzer-template/packages/github/dist/database/src/lib/loadCommit.js.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/loadCommits.d.ts +3 -1
- package/analyzer-template/packages/github/dist/database/src/lib/loadCommits.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/loadCommits.js +22 -1
- package/analyzer-template/packages/github/dist/database/src/lib/loadCommits.js.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/loadEntities.d.ts +3 -1
- package/analyzer-template/packages/github/dist/database/src/lib/loadEntities.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/loadEntities.js +23 -4
- package/analyzer-template/packages/github/dist/database/src/lib/loadEntities.js.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/loadEntityBranches.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/loadEntityBranches.js +9 -0
- package/analyzer-template/packages/github/dist/database/src/lib/loadEntityBranches.js.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/database/src/lib/projectToDb.js +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/projectToDb.js.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/saveFiles.js +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/saveFiles.js.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/scenarioToDb.js +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/scenarioToDb.js.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/updateCommitMetadata.d.ts +2 -2
- package/analyzer-template/packages/github/dist/database/src/lib/updateCommitMetadata.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/updateCommitMetadata.js +5 -4
- package/analyzer-template/packages/github/dist/database/src/lib/updateCommitMetadata.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/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 +3 -4
- package/analyzer-template/packages/github/dist/types/index.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/types/index.js +0 -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 +71 -27
- package/analyzer-template/packages/github/dist/types/src/types/Analysis.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/types/src/types/Commit.d.ts +2 -0
- package/analyzer-template/packages/github/dist/types/src/types/Commit.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/ProjectMetadata.d.ts +7 -0
- package/analyzer-template/packages/github/dist/types/src/types/ProjectMetadata.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/types/src/types/Scenario.d.ts +9 -54
- package/analyzer-template/packages/github/dist/types/src/types/Scenario.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/types/src/types/Scenario.js +1 -21
- package/analyzer-template/packages/github/dist/types/src/types/Scenario.js.map +1 -1
- package/analyzer-template/packages/github/dist/types/src/types/ScenariosDataStructure.d.ts +153 -5
- package/analyzer-template/packages/github/dist/types/src/types/ScenariosDataStructure.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/types/src/types/ScopeAnalysis.d.ts +6 -1
- package/analyzer-template/packages/github/dist/types/src/types/ScopeAnalysis.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/dist/utils/src/lib/safeFileName.d.ts +9 -1
- package/analyzer-template/packages/github/dist/utils/src/lib/safeFileName.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/utils/src/lib/safeFileName.js +29 -3
- package/analyzer-template/packages/github/dist/utils/src/lib/safeFileName.js.map +1 -1
- package/analyzer-template/packages/github/package.json +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 +3 -6
- package/analyzer-template/packages/types/src/types/Analysis.ts +87 -27
- package/analyzer-template/packages/types/src/types/Commit.ts +2 -0
- package/analyzer-template/packages/types/src/types/Entity.ts +2 -0
- package/analyzer-template/packages/types/src/types/ProjectMetadata.ts +7 -0
- package/analyzer-template/packages/types/src/types/Scenario.ts +9 -77
- package/analyzer-template/packages/types/src/types/ScenariosDataStructure.ts +181 -5
- package/analyzer-template/packages/types/src/types/ScopeAnalysis.ts +6 -1
- package/analyzer-template/packages/types/src/types/StatementInfo.ts +2 -0
- package/analyzer-template/packages/utils/dist/types/index.d.ts +3 -4
- package/analyzer-template/packages/utils/dist/types/index.d.ts.map +1 -1
- package/analyzer-template/packages/utils/dist/types/index.js +0 -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 +71 -27
- package/analyzer-template/packages/utils/dist/types/src/types/Analysis.d.ts.map +1 -1
- package/analyzer-template/packages/utils/dist/types/src/types/Commit.d.ts +2 -0
- package/analyzer-template/packages/utils/dist/types/src/types/Commit.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/ProjectMetadata.d.ts +7 -0
- package/analyzer-template/packages/utils/dist/types/src/types/ProjectMetadata.d.ts.map +1 -1
- package/analyzer-template/packages/utils/dist/types/src/types/Scenario.d.ts +9 -54
- package/analyzer-template/packages/utils/dist/types/src/types/Scenario.d.ts.map +1 -1
- package/analyzer-template/packages/utils/dist/types/src/types/Scenario.js +1 -21
- package/analyzer-template/packages/utils/dist/types/src/types/Scenario.js.map +1 -1
- package/analyzer-template/packages/utils/dist/types/src/types/ScenariosDataStructure.d.ts +153 -5
- package/analyzer-template/packages/utils/dist/types/src/types/ScenariosDataStructure.d.ts.map +1 -1
- package/analyzer-template/packages/utils/dist/types/src/types/ScopeAnalysis.d.ts +6 -1
- package/analyzer-template/packages/utils/dist/types/src/types/ScopeAnalysis.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/packages/utils/dist/utils/src/lib/fs/rsyncCopy.d.ts.map +1 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/fs/rsyncCopy.js +93 -2
- package/analyzer-template/packages/utils/dist/utils/src/lib/fs/rsyncCopy.js.map +1 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/safeFileName.d.ts +9 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/safeFileName.d.ts.map +1 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/safeFileName.js +29 -3
- package/analyzer-template/packages/utils/dist/utils/src/lib/safeFileName.js.map +1 -1
- package/analyzer-template/packages/utils/src/lib/fs/rsyncCopy.ts +108 -2
- package/analyzer-template/packages/utils/src/lib/safeFileName.ts +48 -3
- package/analyzer-template/playwright/capture.ts +57 -26
- package/analyzer-template/playwright/captureStatic.ts +1 -1
- package/analyzer-template/playwright/getCodeYamInfo.ts +12 -7
- package/analyzer-template/playwright/waitForServer.ts +21 -6
- package/analyzer-template/project/analyzeBaselineCommit.ts +9 -0
- package/analyzer-template/project/analyzeBranchCommit.ts +4 -0
- package/analyzer-template/project/analyzeFileEntities.ts +4 -0
- package/analyzer-template/project/analyzeRegularCommit.ts +9 -0
- package/analyzer-template/project/captureLibraryFunctionDirect.ts +29 -26
- package/analyzer-template/project/constructMockCode.ts +1201 -178
- package/analyzer-template/project/controller/startController.ts +16 -1
- package/analyzer-template/project/createEntitiesAndSortFiles.ts +83 -0
- package/analyzer-template/project/executeLibraryFunctionDirect.ts +7 -3
- package/analyzer-template/project/loadReadyToBeCaptured.ts +65 -41
- package/analyzer-template/project/mocks/analyzeFileMock.ts +8 -7
- package/analyzer-template/project/orchestrateCapture/AwsCaptureTaskRunner.ts +12 -4
- package/analyzer-template/project/orchestrateCapture/KyselyAnalysisLoader.ts +3 -6
- package/analyzer-template/project/orchestrateCapture/SequentialCaptureTaskRunner.ts +18 -7
- package/analyzer-template/project/orchestrateCapture/taskRunner.ts +4 -2
- package/analyzer-template/project/orchestrateCapture.ts +81 -9
- package/analyzer-template/project/reconcileMockDataKeys.ts +220 -78
- package/analyzer-template/project/runAnalysis.ts +11 -0
- package/analyzer-template/project/serverOnlyModules.ts +127 -2
- package/analyzer-template/project/start.ts +51 -15
- package/analyzer-template/project/startScenarioCapture.ts +6 -0
- package/analyzer-template/project/writeMockDataTsx.ts +345 -32
- package/analyzer-template/project/writeScenarioClientWrapper.ts +21 -0
- package/analyzer-template/project/writeScenarioComponents.ts +358 -118
- package/analyzer-template/project/writeScenarioFiles.ts +26 -0
- package/analyzer-template/project/writeSimpleRoot.ts +28 -42
- package/analyzer-template/scripts/comboWorkerLoop.cjs +99 -50
- package/analyzer-template/scripts/defaultCmd.sh +9 -0
- package/analyzer-template/tsconfig.json +2 -1
- package/background/src/lib/local/createLocalAnalyzer.js +2 -30
- 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 +7 -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 +7 -1
- package/background/src/lib/virtualized/project/analyzeRegularCommit.js.map +1 -1
- package/background/src/lib/virtualized/project/captureLibraryFunctionDirect.js +3 -3
- package/background/src/lib/virtualized/project/captureLibraryFunctionDirect.js.map +1 -1
- package/background/src/lib/virtualized/project/constructMockCode.js +1062 -134
- 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/createEntitiesAndSortFiles.js +73 -1
- package/background/src/lib/virtualized/project/createEntitiesAndSortFiles.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/loadReadyToBeCaptured.js +19 -8
- package/background/src/lib/virtualized/project/loadReadyToBeCaptured.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/AwsCaptureTaskRunner.js +2 -2
- package/background/src/lib/virtualized/project/orchestrateCapture/AwsCaptureTaskRunner.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 +7 -5
- package/background/src/lib/virtualized/project/orchestrateCapture/SequentialCaptureTaskRunner.js.map +1 -1
- package/background/src/lib/virtualized/project/orchestrateCapture.js +65 -10
- package/background/src/lib/virtualized/project/orchestrateCapture.js.map +1 -1
- package/background/src/lib/virtualized/project/reconcileMockDataKeys.js +188 -47
- package/background/src/lib/virtualized/project/reconcileMockDataKeys.js.map +1 -1
- package/background/src/lib/virtualized/project/runAnalysis.js +9 -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 +47 -15
- package/background/src/lib/virtualized/project/start.js.map +1 -1
- package/background/src/lib/virtualized/project/startScenarioCapture.js +7 -0
- package/background/src/lib/virtualized/project/startScenarioCapture.js.map +1 -1
- package/background/src/lib/virtualized/project/writeMockDataTsx.js +301 -27
- 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 +278 -100
- 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 +28 -41
- package/background/src/lib/virtualized/project/writeSimpleRoot.js.map +1 -1
- package/codeyam-cli/scripts/apply-setup.js +180 -0
- package/codeyam-cli/scripts/apply-setup.js.map +1 -1
- package/codeyam-cli/src/cli.js +9 -1
- package/codeyam-cli/src/cli.js.map +1 -1
- package/codeyam-cli/src/codeyam-cli.js +18 -2
- package/codeyam-cli/src/codeyam-cli.js.map +1 -1
- package/codeyam-cli/src/commands/analyze.js +5 -3
- package/codeyam-cli/src/commands/analyze.js.map +1 -1
- package/codeyam-cli/src/commands/baseline.js +176 -0
- package/codeyam-cli/src/commands/baseline.js.map +1 -0
- package/codeyam-cli/src/commands/debug.js +37 -23
- package/codeyam-cli/src/commands/debug.js.map +1 -1
- package/codeyam-cli/src/commands/default.js +30 -34
- package/codeyam-cli/src/commands/default.js.map +1 -1
- package/codeyam-cli/src/commands/detect-universal-mocks.js +2 -0
- package/codeyam-cli/src/commands/detect-universal-mocks.js.map +1 -1
- package/codeyam-cli/src/commands/init.js +49 -257
- package/codeyam-cli/src/commands/init.js.map +1 -1
- package/codeyam-cli/src/commands/memory.js +264 -0
- package/codeyam-cli/src/commands/memory.js.map +1 -0
- package/codeyam-cli/src/commands/recapture.js +31 -18
- package/codeyam-cli/src/commands/recapture.js.map +1 -1
- package/codeyam-cli/src/commands/report.js +46 -1
- package/codeyam-cli/src/commands/report.js.map +1 -1
- package/codeyam-cli/src/commands/setup-sandbox.js +2 -0
- package/codeyam-cli/src/commands/setup-sandbox.js.map +1 -1
- package/codeyam-cli/src/commands/setup-simulations.js +284 -0
- package/codeyam-cli/src/commands/setup-simulations.js.map +1 -0
- 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 +3 -1
- package/codeyam-cli/src/commands/test-startup.js.map +1 -1
- package/codeyam-cli/src/commands/verify.js +14 -2
- package/codeyam-cli/src/commands/verify.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 +128 -82
- package/codeyam-cli/src/utils/__tests__/setupClaudeCodeSettings.test.js.map +1 -1
- package/codeyam-cli/src/utils/analysisRunner.js +29 -15
- package/codeyam-cli/src/utils/analysisRunner.js.map +1 -1
- package/codeyam-cli/src/utils/analyzer.js +7 -0
- package/codeyam-cli/src/utils/analyzer.js.map +1 -1
- package/codeyam-cli/src/utils/backgroundServer.js +112 -21
- 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 +4 -3
- 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 +76 -37
- package/codeyam-cli/src/utils/install-skills.js.map +1 -1
- package/codeyam-cli/src/utils/labsAutoCheck.js +19 -0
- package/codeyam-cli/src/utils/labsAutoCheck.js.map +1 -0
- package/codeyam-cli/src/utils/progress.js +7 -0
- package/codeyam-cli/src/utils/progress.js.map +1 -1
- package/codeyam-cli/src/utils/queue/job.js +109 -0
- package/codeyam-cli/src/utils/queue/job.js.map +1 -1
- package/codeyam-cli/src/utils/queue/manager.js +6 -0
- 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/requireSimulations.js +10 -0
- package/codeyam-cli/src/utils/requireSimulations.js.map +1 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/confusionDetector.test.js +82 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/confusionDetector.test.js.map +1 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/contextBuilder.test.js +230 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/contextBuilder.test.js.map +1 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/assertRules.js +67 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/assertRules.js.map +1 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/captureFixture.js +105 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/captureFixture.js.map +1 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/loadCapturedFixture.js +34 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/loadCapturedFixture.js.map +1 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/runClaude.js +162 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/runClaude.js.map +1 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/setupTempProject.js +75 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/setupTempProject.js.map +1 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/ruleReflectionE2E.test.js +378 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/ruleReflectionE2E.test.js.map +1 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/promptBuilder.test.js +115 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/promptBuilder.test.js.map +1 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/transcriptParser.test.js +127 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/transcriptParser.test.js.map +1 -0
- package/codeyam-cli/src/utils/ruleReflection/confusionDetector.js +50 -0
- package/codeyam-cli/src/utils/ruleReflection/confusionDetector.js.map +1 -0
- package/codeyam-cli/src/utils/ruleReflection/contextBuilder.js +116 -0
- package/codeyam-cli/src/utils/ruleReflection/contextBuilder.js.map +1 -0
- package/codeyam-cli/src/utils/ruleReflection/index.js +5 -0
- package/codeyam-cli/src/utils/ruleReflection/index.js.map +1 -0
- package/codeyam-cli/src/utils/ruleReflection/promptBuilder.js +44 -0
- package/codeyam-cli/src/utils/ruleReflection/promptBuilder.js.map +1 -0
- package/codeyam-cli/src/utils/ruleReflection/transcriptParser.js +85 -0
- package/codeyam-cli/src/utils/ruleReflection/transcriptParser.js.map +1 -0
- package/codeyam-cli/src/utils/ruleReflection/types.js +5 -0
- package/codeyam-cli/src/utils/ruleReflection/types.js.map +1 -0
- package/codeyam-cli/src/utils/rules/__tests__/ruleState.test.js +293 -0
- package/codeyam-cli/src/utils/rules/__tests__/ruleState.test.js.map +1 -0
- package/codeyam-cli/src/utils/rules/index.js +6 -0
- package/codeyam-cli/src/utils/rules/index.js.map +1 -0
- package/codeyam-cli/src/utils/rules/parser.js +83 -0
- package/codeyam-cli/src/utils/rules/parser.js.map +1 -0
- package/codeyam-cli/src/utils/rules/pathMatcher.js +18 -0
- package/codeyam-cli/src/utils/rules/pathMatcher.js.map +1 -0
- package/codeyam-cli/src/utils/rules/ruleState.js +150 -0
- package/codeyam-cli/src/utils/rules/ruleState.js.map +1 -0
- package/codeyam-cli/src/utils/rules/staleness.js +137 -0
- package/codeyam-cli/src/utils/rules/staleness.js.map +1 -0
- package/codeyam-cli/src/utils/serverState.js +37 -10
- package/codeyam-cli/src/utils/serverState.js.map +1 -1
- package/codeyam-cli/src/utils/setupClaudeCodeSettings.js +21 -42
- package/codeyam-cli/src/utils/setupClaudeCodeSettings.js.map +1 -1
- 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 +88 -23
- 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 +50 -0
- package/codeyam-cli/src/webserver/backgroundServer.js.map +1 -1
- package/codeyam-cli/src/webserver/bootstrap.js +51 -0
- package/codeyam-cli/src/webserver/bootstrap.js.map +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/CopyButton-D9i_zSlY.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/EntityItem-BLlhOa3C.js +11 -0
- package/codeyam-cli/src/webserver/build/client/assets/{EntityTypeBadge-CzGX-miz.js → EntityTypeBadge-De5b5pC7.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/EntityTypeIcon-CzdG5I7z.js +41 -0
- package/codeyam-cli/src/webserver/build/client/assets/InlineSpinner-Bclf8Hka.js +34 -0
- package/codeyam-cli/src/webserver/build/client/assets/InteractivePreview-Ce-byqKl.js +25 -0
- package/codeyam-cli/src/webserver/build/client/assets/{LibraryFunctionPreview-CBQPrpT0.js → LibraryFunctionPreview-DEMHrl7v.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{LoadingDots-D1CdlbrV.js → LoadingDots-B1LNGboS.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{LogViewer-wDPcZNKx.js → LogViewer-B0Ll1DjK.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/ReportIssueModal-CVOvmCKb.js +11 -0
- package/codeyam-cli/src/webserver/build/client/assets/{SafeScreenshot-BfmDgXxG.js → SafeScreenshot-L0DWHa_L.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/ScenarioViewer-D54Mmpwi.js +10 -0
- package/codeyam-cli/src/webserver/build/client/assets/{TruncatedFilePath-6J7zDUD5.js → TruncatedFilePath-C7PFQfXy.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/_index-CKTtYlBU.js +11 -0
- package/codeyam-cli/src/webserver/build/client/assets/activity.(_tab)-CdziRIWU.js +27 -0
- package/codeyam-cli/src/webserver/build/client/assets/agent-transcripts-CPXtdaWm.js +17 -0
- package/codeyam-cli/src/webserver/build/client/assets/api.memory-profile-l0sNRNKZ.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/api.restart-server-l0sNRNKZ.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/api.save-fixture-l0sNRNKZ.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/book-open-Ch8b7GyQ.js +6 -0
- package/codeyam-cli/src/webserver/build/client/assets/{chevron-down-BYimnrHg.js → chevron-down-vJHJExlT.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/chunk-JZWAC4HX-BEyX4X6_.js +51 -0
- package/codeyam-cli/src/webserver/build/client/assets/{circle-check-CaVsIRxt.js → circle-check-rwynPZTW.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/copy-BBSpeBYf.js +11 -0
- package/codeyam-cli/src/webserver/build/client/assets/{createLucideIcon-CgUsG7ib.js → createLucideIcon-DHVDauuc.js} +1 -1
- 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-B9_ZqelV.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha._-BOPComvD.js +16 -0
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha.scenarios._scenarioId.fullscreen-Cfw__yQa.js +6 -0
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.create-scenario-BIDUUrI3.js +6 -0
- package/codeyam-cli/src/webserver/build/client/assets/{entity._sha_.edit._scenarioId-CfLCUi9S.js → entity._sha_.edit._scenarioId-BEqewwtZ.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{entry.client-DKJyZfAY.js → entry.client-Dxqz8ygt.js} +6 -6
- package/codeyam-cli/src/webserver/build/client/assets/executionFlowCoverage-BWhdfn70.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{fileTableUtils-DAtOlaWE.js → fileTableUtils-CYnF5KWN.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/files-B_dAq2PQ.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{git-D62Lxxmv.js → git-BHPqH3Ch.js} +8 -8
- package/codeyam-cli/src/webserver/build/client/assets/globals-BJGhRykz.css +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{index-BosqDOlH.js → index-DgAAopZk.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{index-CzNNiTkw.js → index-viijWaN6.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/labs-ChoAe3xq.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{loader-circle-CNp9QFCX.js → loader-circle-LGi2eKI5.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/manifest-87493a32.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/memory-D9eA6kTo.js +78 -0
- package/codeyam-cli/src/webserver/build/client/assets/pause-DxJFmMsK.js +11 -0
- package/codeyam-cli/src/webserver/build/client/assets/root-C3r0p_7H.js +62 -0
- package/codeyam-cli/src/webserver/build/client/assets/{search-DDGjYAMJ.js → search-Cu3QE9E5.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/settings-KH9TdArD.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/simulations-D9Fkx0-d.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/terminal-dAhIBEcd.js +11 -0
- package/codeyam-cli/src/webserver/build/client/assets/{triangle-alert-CBc5dE1s.js → triangle-alert-C4CYTEeP.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/useCustomSizes-CLPnITMB.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{useLastLogLine-BqPPNjAl.js → useLastLogLine-DmGI38Et.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/useReportContext-BK0S88PB.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{useToast-DWHcCcl1.js → useToast-CJ-JqR0l.js} +1 -1
- package/codeyam-cli/src/webserver/build/server/assets/index-CkkmL6r5.js +1 -0
- package/codeyam-cli/src/webserver/build/server/assets/server-build-iBGjHYtO.js +259 -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/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} +48 -4
- package/codeyam-cli/templates/codeyam-diagnose.md +481 -0
- package/codeyam-cli/templates/codeyam-memory-hook.sh +199 -0
- package/codeyam-cli/templates/codeyam-memory.md +396 -0
- package/codeyam-cli/templates/codeyam-new-rule.md +13 -0
- package/codeyam-cli/templates/{codeyam-setup-skill.md → codeyam-setup.md} +151 -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/codeyam-cli/templates/rule-notification-hook.py +56 -0
- package/codeyam-cli/templates/rule-reflection-hook.py +627 -0
- package/codeyam-cli/templates/rules-instructions.md +132 -0
- package/package.json +17 -14
- package/packages/ai/index.js +8 -6
- package/packages/ai/index.js.map +1 -1
- package/packages/ai/src/lib/analyzeScope.js +179 -13
- package/packages/ai/src/lib/analyzeScope.js.map +1 -1
- package/packages/ai/src/lib/astScopes/arrayDerivationDetector.js +150 -0
- package/packages/ai/src/lib/astScopes/arrayDerivationDetector.js.map +1 -0
- package/packages/ai/src/lib/astScopes/astScopeAnalyzer.js +138 -9
- 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 +138 -23
- package/packages/ai/src/lib/astScopes/methodSemantics.js.map +1 -1
- package/packages/ai/src/lib/astScopes/patterns/forInStatementHandler.js +10 -14
- package/packages/ai/src/lib/astScopes/patterns/forInStatementHandler.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 +7 -0
- package/packages/ai/src/lib/astScopes/patterns/switchStatementHandler.js.map +1 -1
- package/packages/ai/src/lib/astScopes/patterns/variableDeclarationHandler.js +138 -1
- package/packages/ai/src/lib/astScopes/patterns/variableDeclarationHandler.js.map +1 -1
- package/packages/ai/src/lib/astScopes/processExpression.js +944 -30
- package/packages/ai/src/lib/astScopes/processExpression.js.map +1 -1
- package/packages/ai/src/lib/astScopes/sharedPatterns.js +25 -0
- package/packages/ai/src/lib/astScopes/sharedPatterns.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 +178 -31
- package/packages/ai/src/lib/completionCall.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js +1461 -205
- package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/JavascriptFrameworkManager.js +7 -2
- package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/JavascriptFrameworkManager.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/MuiManager.js +230 -23
- package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/MuiManager.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/ReactFrameworkManager.js +77 -55
- package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/ReactFrameworkManager.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/helpers/BatchSchemaProcessor.js +13 -3
- package/packages/ai/src/lib/dataStructure/helpers/BatchSchemaProcessor.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/helpers/ScopeTreeManager.js +6 -4
- package/packages/ai/src/lib/dataStructure/helpers/ScopeTreeManager.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.js +52 -3
- package/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/helpers/cleanNonObjectFunctions.js +122 -14
- package/packages/ai/src/lib/dataStructure/helpers/cleanNonObjectFunctions.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/helpers/coerceObjectsToPrimitivesBySchema.js +63 -0
- package/packages/ai/src/lib/dataStructure/helpers/coerceObjectsToPrimitivesBySchema.js.map +1 -0
- package/packages/ai/src/lib/dataStructure/helpers/convertDotNotation.js +122 -12
- 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/convertTypeAnnotationsToValues.js +173 -0
- package/packages/ai/src/lib/dataStructure/helpers/convertTypeAnnotationsToValues.js.map +1 -0
- package/packages/ai/src/lib/dataStructure/helpers/deduplicateFunctionSchemas.js +37 -20
- package/packages/ai/src/lib/dataStructure/helpers/deduplicateFunctionSchemas.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.js +333 -81
- package/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/helpers/fixNullIdsBySchema.js +107 -0
- package/packages/ai/src/lib/dataStructure/helpers/fixNullIdsBySchema.js.map +1 -0
- package/packages/ai/src/lib/dataStructureChunking.js +126 -0
- package/packages/ai/src/lib/dataStructureChunking.js.map +1 -0
- package/packages/ai/src/lib/deepEqual.js +32 -0
- package/packages/ai/src/lib/deepEqual.js.map +1 -0
- package/packages/ai/src/lib/e2eDataTracking.js +241 -0
- package/packages/ai/src/lib/e2eDataTracking.js.map +1 -0
- package/packages/ai/src/lib/extractCriticalDataKeys.js +96 -0
- package/packages/ai/src/lib/extractCriticalDataKeys.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 +78 -120
- package/packages/ai/src/lib/generateChangesEntityScenarios.js.map +1 -1
- package/packages/ai/src/lib/generateEntityDataStructure.js +47 -2
- package/packages/ai/src/lib/generateEntityDataStructure.js.map +1 -1
- package/packages/ai/src/lib/generateEntityScenarioData.js +1130 -83
- package/packages/ai/src/lib/generateEntityScenarioData.js.map +1 -1
- package/packages/ai/src/lib/generateEntityScenarios.js +177 -163
- package/packages/ai/src/lib/generateEntityScenarios.js.map +1 -1
- package/packages/ai/src/lib/generateExecutionFlows.js +414 -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 +1807 -0
- package/packages/ai/src/lib/generateExecutionFlowsFromConditionals.js.map +1 -0
- package/packages/ai/src/lib/generateExecutionFlowsFromJsxUsages.js +194 -0
- package/packages/ai/src/lib/generateExecutionFlowsFromJsxUsages.js.map +1 -0
- package/packages/ai/src/lib/guessScenarioDataFromDescription.js +2 -2
- package/packages/ai/src/lib/guessScenarioDataFromDescription.js.map +1 -1
- package/packages/ai/src/lib/isolateScopes.js +270 -7
- package/packages/ai/src/lib/isolateScopes.js.map +1 -1
- package/packages/ai/src/lib/mergeJsonTypeDefinitions.js +5 -0
- package/packages/ai/src/lib/mergeJsonTypeDefinitions.js.map +1 -1
- package/packages/ai/src/lib/mergeStatements.js +88 -46
- package/packages/ai/src/lib/mergeStatements.js.map +1 -1
- package/packages/ai/src/lib/promptGenerators/collapseNullableObjects.js +97 -0
- package/packages/ai/src/lib/promptGenerators/collapseNullableObjects.js.map +1 -0
- package/packages/ai/src/lib/promptGenerators/gatherAttributesMap.js +10 -4
- 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 -100
- package/packages/ai/src/lib/promptGenerators/generateChangesEntityScenariosGenerator.js.map +1 -1
- package/packages/ai/src/lib/promptGenerators/generateChunkPrompt.js +54 -0
- package/packages/ai/src/lib/promptGenerators/generateChunkPrompt.js.map +1 -0
- package/packages/ai/src/lib/promptGenerators/generateEntityScenarioDataGenerator.js +83 -6
- package/packages/ai/src/lib/promptGenerators/generateEntityScenarioDataGenerator.js.map +1 -1
- package/packages/ai/src/lib/promptGenerators/generateEntityScenariosGenerator.js +10 -70
- 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 +9 -9
- package/packages/ai/src/lib/promptGenerators/guessNewScenarioDataFromDescriptionGenerator.js.map +1 -1
- package/packages/ai/src/lib/promptGenerators/simplifyKeysForLLM.js +335 -0
- package/packages/ai/src/lib/promptGenerators/simplifyKeysForLLM.js.map +1 -0
- package/packages/ai/src/lib/resolvePathToControllable.js +677 -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 +29 -0
- package/packages/ai/src/lib/worker/SerializableDataStructure.js.map +1 -1
- package/packages/ai/src/lib/worker/analyzeScopeWorker.js +94 -1
- package/packages/ai/src/lib/worker/analyzeScopeWorker.js.map +1 -1
- package/packages/analyze/index.js +1 -0
- package/packages/analyze/index.js.map +1 -1
- package/packages/analyze/src/lib/FileAnalyzer.js +75 -36
- package/packages/analyze/src/lib/FileAnalyzer.js.map +1 -1
- package/packages/analyze/src/lib/ProjectAnalyzer.js +96 -26
- package/packages/analyze/src/lib/ProjectAnalyzer.js.map +1 -1
- package/packages/analyze/src/lib/analysisContext.js +30 -5
- package/packages/analyze/src/lib/analysisContext.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/asts/sourceFiles/getAllDeclaredEntityNodes.js +14 -0
- package/packages/analyze/src/lib/asts/sourceFiles/getAllDeclaredEntityNodes.js.map +1 -1
- package/packages/analyze/src/lib/asts/sourceFiles/getAllEntityNodes.js +14 -0
- package/packages/analyze/src/lib/asts/sourceFiles/getAllEntityNodes.js.map +1 -1
- package/packages/analyze/src/lib/asts/sourceFiles/getAllExports.js +6 -0
- package/packages/analyze/src/lib/asts/sourceFiles/getAllExports.js.map +1 -1
- package/packages/analyze/src/lib/asts/sourceFiles/getImportsAnalysis.js +6 -0
- package/packages/analyze/src/lib/asts/sourceFiles/getImportsAnalysis.js.map +1 -1
- package/packages/analyze/src/lib/asts/sourceFiles/getResolvedModule.js +39 -1
- package/packages/analyze/src/lib/asts/sourceFiles/getResolvedModule.js.map +1 -1
- package/packages/analyze/src/lib/asts/sourceFiles/getSourceFilesForAllImports.js +2 -1
- package/packages/analyze/src/lib/asts/sourceFiles/getSourceFilesForAllImports.js.map +1 -1
- package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js +211 -54
- package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js.map +1 -1
- package/packages/analyze/src/lib/files/analyze/analyzeEntities.js +24 -1
- package/packages/analyze/src/lib/files/analyze/analyzeEntities.js.map +1 -1
- package/packages/analyze/src/lib/files/analyze/dependencyResolver.js +5 -0
- package/packages/analyze/src/lib/files/analyze/dependencyResolver.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/analyze/gatherEntityMap.js +2 -1
- package/packages/analyze/src/lib/files/analyze/gatherEntityMap.js.map +1 -1
- package/packages/analyze/src/lib/files/analyze/validateDependencyAnalyses.js +31 -10
- package/packages/analyze/src/lib/files/analyze/validateDependencyAnalyses.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/analyzeRemixRoute.js +3 -2
- package/packages/analyze/src/lib/files/analyzeRemixRoute.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/getImportedExports.js +11 -7
- package/packages/analyze/src/lib/files/getImportedExports.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/TransformationTracer.js +880 -0
- package/packages/analyze/src/lib/files/scenarios/TransformationTracer.js.map +1 -0
- package/packages/analyze/src/lib/files/scenarios/enrichArrayTypesFromChildSignatures.js +170 -40
- package/packages/analyze/src/lib/files/scenarios/enrichArrayTypesFromChildSignatures.js.map +1 -1
- 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 +480 -71
- package/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.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 +268 -66
- package/packages/analyze/src/lib/files/scenarios/generateDataStructure.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/generateExecutionFlows.js +144 -0
- package/packages/analyze/src/lib/files/scenarios/generateExecutionFlows.js.map +1 -0
- package/packages/analyze/src/lib/files/scenarios/generateScenarioData.js +27 -98
- package/packages/analyze/src/lib/files/scenarios/generateScenarioData.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/generateScenarios.js +2 -3
- package/packages/analyze/src/lib/files/scenarios/generateScenarios.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js +801 -118
- package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/mergeValidatedDataStructures.js +46 -9
- package/packages/analyze/src/lib/files/scenarios/mergeValidatedDataStructures.js.map +1 -1
- package/packages/analyze/src/lib/files/setImportedExports.js +2 -1
- package/packages/analyze/src/lib/files/setImportedExports.js.map +1 -1
- package/packages/analyze/src/lib/index.js +1 -0
- package/packages/analyze/src/lib/index.js.map +1 -1
- package/packages/analyze/src/lib/utils/getFileByPath.js +12 -0
- package/packages/analyze/src/lib/utils/getFileByPath.js.map +1 -0
- 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/analysisBranchToDb.js +1 -1
- package/packages/database/src/lib/analysisBranchToDb.js.map +1 -1
- package/packages/database/src/lib/analysisToDb.js +1 -1
- package/packages/database/src/lib/analysisToDb.js.map +1 -1
- package/packages/database/src/lib/branchToDb.js +1 -1
- package/packages/database/src/lib/branchToDb.js.map +1 -1
- package/packages/database/src/lib/commitBranchToDb.js +1 -1
- package/packages/database/src/lib/commitBranchToDb.js.map +1 -1
- package/packages/database/src/lib/commitToDb.js +1 -1
- package/packages/database/src/lib/commitToDb.js.map +1 -1
- package/packages/database/src/lib/fileToDb.js +1 -1
- package/packages/database/src/lib/fileToDb.js.map +1 -1
- package/packages/database/src/lib/kysely/db.js +11 -1
- package/packages/database/src/lib/kysely/db.js.map +1 -1
- package/packages/database/src/lib/kysely/tables/commitsTable.js +3 -0
- package/packages/database/src/lib/kysely/tables/commitsTable.js.map +1 -1
- package/packages/database/src/lib/kysely/tables/debugReportsTable.js.map +1 -1
- package/packages/database/src/lib/kysely/tables/labsRequestsTable.js +35 -0
- package/packages/database/src/lib/kysely/tables/labsRequestsTable.js.map +1 -0
- package/packages/database/src/lib/loadAnalyses.js +45 -2
- package/packages/database/src/lib/loadAnalyses.js.map +1 -1
- package/packages/database/src/lib/loadAnalysis.js +8 -0
- package/packages/database/src/lib/loadAnalysis.js.map +1 -1
- package/packages/database/src/lib/loadBranch.js +11 -1
- package/packages/database/src/lib/loadBranch.js.map +1 -1
- package/packages/database/src/lib/loadCommit.js +7 -0
- package/packages/database/src/lib/loadCommit.js.map +1 -1
- package/packages/database/src/lib/loadCommits.js +22 -1
- package/packages/database/src/lib/loadCommits.js.map +1 -1
- package/packages/database/src/lib/loadEntities.js +23 -4
- package/packages/database/src/lib/loadEntities.js.map +1 -1
- package/packages/database/src/lib/loadEntityBranches.js +9 -0
- package/packages/database/src/lib/loadEntityBranches.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/database/src/lib/projectToDb.js +1 -1
- package/packages/database/src/lib/projectToDb.js.map +1 -1
- package/packages/database/src/lib/saveFiles.js +1 -1
- package/packages/database/src/lib/saveFiles.js.map +1 -1
- package/packages/database/src/lib/scenarioToDb.js +1 -1
- package/packages/database/src/lib/scenarioToDb.js.map +1 -1
- package/packages/database/src/lib/updateCommitMetadata.js +5 -4
- package/packages/database/src/lib/updateCommitMetadata.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/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 +0 -1
- package/packages/types/index.js.map +1 -1
- package/packages/types/src/types/Scenario.js +1 -21
- package/packages/types/src/types/Scenario.js.map +1 -1
- package/packages/utils/src/lib/fs/rsyncCopy.js +93 -2
- package/packages/utils/src/lib/fs/rsyncCopy.js.map +1 -1
- package/packages/utils/src/lib/safeFileName.js +29 -3
- package/packages/utils/src/lib/safeFileName.js.map +1 -1
- package/scripts/finalize-analyzer.cjs +8 -76
- package/analyzer-template/packages/ai/src/lib/findMatchingAttribute.ts +0 -102
- package/analyzer-template/packages/ai/src/lib/gatherRelevantDependentKeyAttributes.ts +0 -409
- package/analyzer-template/packages/ai/src/lib/generateChangesEntityKeyAttributes.ts +0 -288
- package/analyzer-template/packages/ai/src/lib/generateEntityKeyAttributes.ts +0 -495
- package/analyzer-template/packages/ai/src/lib/promptGenerators/generateEntityKeyAttributesGenerator.ts +0 -67
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateKeyAttributes.ts +0 -120
- 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/scripts/fixtures/formbricks/universal-mocks/apps/web/lib/instance/service.js +0 -7
- package/codeyam-cli/scripts/fixtures/formbricks/universal-mocks/apps/web/lib/instance/service.js.map +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/EntityItem-wXL1Z2Aq.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/EntityTypeIcon-CXFKsCOD.js +0 -41
- package/codeyam-cli/src/webserver/build/client/assets/InteractivePreview-D-9pXIaY.js +0 -25
- package/codeyam-cli/src/webserver/build/client/assets/ReportIssueModal-4lcOlid-.js +0 -11
- package/codeyam-cli/src/webserver/build/client/assets/ScenarioViewer-CUxUNEEC.js +0 -15
- package/codeyam-cli/src/webserver/build/client/assets/_index-DHImXdXq.js +0 -11
- package/codeyam-cli/src/webserver/build/client/assets/activity.(_tab)-2mG6mjVb.js +0 -32
- package/codeyam-cli/src/webserver/build/client/assets/chunk-JMJ3UQ3L-BambyYE_.js +0 -51
- package/codeyam-cli/src/webserver/build/client/assets/cy-logo-cli-CKnwPCDr.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/dev.empty-DW_hdGUc.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha._-zUEpfPsu.js +0 -23
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha.scenarios._scenarioId.fullscreen-DyB90fWk.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.create-scenario-D_3ero5o.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/files-ClR0d32A.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/globals-C6vQASxy.css +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/keyAttributeCoverage-CTlFMihX.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/manifest-09d684be.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/root-BxJUvKau.js +0 -56
- package/codeyam-cli/src/webserver/build/client/assets/settings-DgTyB-Wg.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/simulations-CoNWGt0K.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/useCustomSizes-BMIGFP-m.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/useInteractiveMode-Dk_FQqWJ.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/useReportContext-DsJbgMY9.js +0 -1
- package/codeyam-cli/src/webserver/build/server/assets/index-CV6i1S1A.js +0 -1
- package/codeyam-cli/src/webserver/build/server/assets/server-build-BDlyhfrv.js +0 -175
- package/codeyam-cli/templates/debug-codeyam.md +0 -620
- 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 -298
- package/packages/ai/src/lib/gatherRelevantDependentKeyAttributes.js.map +0 -1
- package/packages/ai/src/lib/generateChangesEntityKeyAttributes.js +0 -226
- package/packages/ai/src/lib/generateChangesEntityKeyAttributes.js.map +0 -1
- package/packages/ai/src/lib/generateEntityKeyAttributes.js +0 -408
- 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 -77
- 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/codeyam-cli/src/webserver/build/client/assets/{api.link-scenario-value-l0sNRNKZ.js → api.agent-transcripts-l0sNRNKZ.js} +0 -0
- /package/codeyam-cli/src/webserver/build/client/assets/{api.update-key-attributes-l0sNRNKZ.js → api.health-l0sNRNKZ.js} +0 -0
- /package/codeyam-cli/src/webserver/build/client/assets/{api.update-valid-values-l0sNRNKZ.js → api.labs-unlock-l0sNRNKZ.js} +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
|
@@ -25,13 +25,102 @@ interface ReturnValuePart {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
|
-
* Converts a
|
|
29
|
-
*
|
|
28
|
+
* Converts a call signature to a valid JavaScript identifier (function name).
|
|
29
|
+
* The original signature is preserved for data access - this only creates the function name.
|
|
30
|
+
*
|
|
31
|
+
* Examples:
|
|
32
|
+
* - "useAuth()" → "useAuth"
|
|
33
|
+
* - "db.select(usersQuery)" → "db_select_usersQuery"
|
|
34
|
+
* - "db.select(postsQuery)" → "db_select_postsQuery"
|
|
35
|
+
* - "useFetcher<User>()" → "useFetcher_User"
|
|
36
|
+
* - "useFetcher<{ data: UserData | null }>()" → "useFetcher_data_UserData_null"
|
|
37
|
+
* - "eq('user_id', value)" → "eq_user_id_value"
|
|
38
|
+
* - "from('workouts')" → "from_workouts"
|
|
30
39
|
*/
|
|
31
|
-
function
|
|
32
|
-
//
|
|
33
|
-
|
|
34
|
-
|
|
40
|
+
function callSignatureToFunctionName(signature: string): string {
|
|
41
|
+
// Extract components from the signature
|
|
42
|
+
const components: string[] = [];
|
|
43
|
+
|
|
44
|
+
// 1. Extract function path (parts separated by dots outside parens/brackets)
|
|
45
|
+
const pathMatch = signature.match(/^([^<(]+)/);
|
|
46
|
+
if (pathMatch) {
|
|
47
|
+
const path = pathMatch[1];
|
|
48
|
+
// Split on dots but preserve the parts
|
|
49
|
+
components.push(...path.split('.').filter(Boolean));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// 2. Extract generic type parameters (content between < and >)
|
|
53
|
+
const genericMatch = signature.match(/<([^>]+)>/);
|
|
54
|
+
if (genericMatch) {
|
|
55
|
+
const genericContent = genericMatch[1];
|
|
56
|
+
// Extract meaningful identifiers from generic type
|
|
57
|
+
// Handle complex types like "{ data: UserData | null }"
|
|
58
|
+
const typeIdentifiers = genericContent
|
|
59
|
+
.replace(/[{}:;,]/g, ' ') // Remove structural chars
|
|
60
|
+
.replace(/\|/g, ' ') // Handle union types
|
|
61
|
+
.split(/\s+/)
|
|
62
|
+
.filter(Boolean)
|
|
63
|
+
.filter((s) => /^[A-Za-z_][A-Za-z0-9_]*$/.test(s)) // Only valid identifiers
|
|
64
|
+
.filter(
|
|
65
|
+
(s) =>
|
|
66
|
+
![
|
|
67
|
+
'null',
|
|
68
|
+
'undefined',
|
|
69
|
+
'void',
|
|
70
|
+
'never',
|
|
71
|
+
'any',
|
|
72
|
+
'unknown',
|
|
73
|
+
'data',
|
|
74
|
+
'typeof',
|
|
75
|
+
].includes(s),
|
|
76
|
+
); // Skip common non-meaningful keywords
|
|
77
|
+
|
|
78
|
+
if (typeIdentifiers.length > 0) {
|
|
79
|
+
components.push(...typeIdentifiers.slice(0, 2)); // Limit to first 2 for reasonable length
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// 3. Extract function arguments (first 2 for disambiguation)
|
|
84
|
+
const argsMatch = signature.match(/\(([^)]*)\)/);
|
|
85
|
+
if (argsMatch && argsMatch[1]) {
|
|
86
|
+
const argsContent = argsMatch[1].trim();
|
|
87
|
+
if (argsContent) {
|
|
88
|
+
const args = argsContent.split(',').map((arg) => arg.trim());
|
|
89
|
+
for (const arg of args.slice(0, 2)) {
|
|
90
|
+
// For quoted strings, extract the content
|
|
91
|
+
const stringMatch = arg.match(/^['"`](.+)['"`]$/);
|
|
92
|
+
if (stringMatch) {
|
|
93
|
+
// Split on dots for string paths like 'users.id'
|
|
94
|
+
const parts = stringMatch[1].split('.').filter(Boolean);
|
|
95
|
+
components.push(...parts);
|
|
96
|
+
} else if (/^[A-Za-z_][A-Za-z0-9_]*$/.test(arg)) {
|
|
97
|
+
// Valid identifier - use as-is
|
|
98
|
+
components.push(arg);
|
|
99
|
+
} else if (/^\d+$/.test(arg)) {
|
|
100
|
+
// Number - use as-is
|
|
101
|
+
components.push(arg);
|
|
102
|
+
}
|
|
103
|
+
// Skip complex expressions
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Build the function name from components
|
|
109
|
+
const functionName = components
|
|
110
|
+
.join('_')
|
|
111
|
+
.replace(/[^a-zA-Z0-9_]/g, '_') // Sanitize special chars
|
|
112
|
+
.replace(/_+/g, '_') // Collapse multiple underscores
|
|
113
|
+
.replace(/^_|_$/g, ''); // Trim underscores
|
|
114
|
+
|
|
115
|
+
return functionName || 'mock';
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Check if a mock name is a call signature (e.g., "useFetcher<User>()", "db.select(query)")
|
|
120
|
+
*/
|
|
121
|
+
function isCallSignature(mockName: string): boolean {
|
|
122
|
+
// Call signatures contain parentheses (function calls)
|
|
123
|
+
return mockName.includes('(');
|
|
35
124
|
}
|
|
36
125
|
|
|
37
126
|
/**
|
|
@@ -196,31 +285,54 @@ function funcArgs(functionSignature: string): string[] {
|
|
|
196
285
|
|
|
197
286
|
// isValidKey ensures that the key does not contain any characters that would make it invalid in a JavaScript object.
|
|
198
287
|
// For example, it should not contain spaces, special characters, or start with a number.
|
|
288
|
+
// Also rejects keys that are pure function calls like "()" or "(args)" - these aren't property names.
|
|
199
289
|
function isValidKey(key: string) {
|
|
200
290
|
if (!key || key.length === 0) return false;
|
|
201
291
|
const keyWithOutArguments = key.split('(')[0];
|
|
292
|
+
// Reject empty keys (happens when key is "()" or "(args)") - these are function calls, not property names
|
|
293
|
+
if (!keyWithOutArguments || keyWithOutArguments.length === 0) return false;
|
|
202
294
|
return !/\s/.test(keyWithOutArguments);
|
|
203
295
|
}
|
|
204
296
|
|
|
297
|
+
/**
|
|
298
|
+
* Known hooks that return tuples [value, setter] instead of arrays.
|
|
299
|
+
* These should NOT use the .map() pattern even when the schema has generic array access ([]).
|
|
300
|
+
* Instead, they should return [data, () => {}] where data is from scenarios().
|
|
301
|
+
*/
|
|
302
|
+
const TUPLE_RETURNING_HOOKS = new Set([
|
|
303
|
+
'useAtom', // Jotai
|
|
304
|
+
'useState', // React
|
|
305
|
+
'useReducer', // React
|
|
306
|
+
'useRecoilState', // Recoil
|
|
307
|
+
'useImmerAtom', // Jotai with Immer
|
|
308
|
+
]);
|
|
309
|
+
|
|
205
310
|
export default function constructMockCode(
|
|
206
311
|
mockName: string,
|
|
207
312
|
dependencySchemas: DeepReadonly<DataStructure['dependencySchemas']>,
|
|
208
313
|
entityType?: EntityType,
|
|
209
|
-
|
|
210
|
-
options?: {
|
|
314
|
+
_canonicalKey?: string, // DEPRECATED: No longer used, kept for API compatibility
|
|
315
|
+
options?: {
|
|
316
|
+
keepOriginalFunctionName?: boolean;
|
|
317
|
+
uniqueFunctionSuffix?: string;
|
|
318
|
+
skipOriginalSpread?: boolean; // Skip spreading from __cyOriginal when it won't be defined
|
|
319
|
+
},
|
|
211
320
|
) {
|
|
212
|
-
// Check
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
? variableQualifierMatch[1]
|
|
321
|
+
// Check if mockName is a call signature (e.g., "useFetcher<User>()", "db.select(query)")
|
|
322
|
+
const mockNameIsCallSignature = isCallSignature(mockName);
|
|
323
|
+
|
|
324
|
+
// For call signatures, use the original signature for data access but generate
|
|
325
|
+
// a valid JS function name from it
|
|
326
|
+
const derivedFunctionName = mockNameIsCallSignature
|
|
327
|
+
? callSignatureToFunctionName(mockName)
|
|
220
328
|
: null;
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
329
|
+
|
|
330
|
+
// The baseMockName is the function name without type params and args
|
|
331
|
+
// e.g., "useFetcher<User>()" -> "useFetcher", "db.select(query)" -> "db"
|
|
332
|
+
const baseMockName = mockName.split(/[<(]/)[0];
|
|
333
|
+
|
|
334
|
+
// The data key is the mockName (call signature) for data access
|
|
335
|
+
let dataKey: string;
|
|
224
336
|
|
|
225
337
|
const mockNameParts = splitOutsideParenthesesAndArrays(baseMockName);
|
|
226
338
|
|
|
@@ -230,33 +342,12 @@ export default function constructMockCode(
|
|
|
230
342
|
let foundEntityWithSignature = false;
|
|
231
343
|
let signatureSchema: DataStructure['signatureSchema'] | undefined;
|
|
232
344
|
|
|
233
|
-
for (const filePath in dependencySchemas) {
|
|
345
|
+
entitySearch: for (const filePath in dependencySchemas) {
|
|
234
346
|
for (const entityName in dependencySchemas[filePath]) {
|
|
235
|
-
//
|
|
236
|
-
|
|
237
|
-
const
|
|
238
|
-
|
|
239
|
-
: mockNameParts[0];
|
|
240
|
-
|
|
241
|
-
// Check for direct match
|
|
242
|
-
let matches =
|
|
243
|
-
entityName === targetEntityName || entityName === mockNameParts[0];
|
|
244
|
-
|
|
245
|
-
// If no direct match and no qualifier was provided, check if the entity
|
|
246
|
-
// is stored under a variable-qualified key (e.g., "stateBadge <- getStateBadge")
|
|
247
|
-
// This handles the case where gatherDataForMocks stored the entity with a variable
|
|
248
|
-
// qualifier but writeScenarioComponents called constructMockCode without one.
|
|
249
|
-
if (!matches && !variableQualifier) {
|
|
250
|
-
const qualifiedKeyMatch = entityName.match(
|
|
251
|
-
new RegExp(`^([a-zA-Z_][a-zA-Z0-9_]*)\\s*<-\\s*${mockNameParts[0]}$`),
|
|
252
|
-
);
|
|
253
|
-
if (qualifiedKeyMatch) {
|
|
254
|
-
matches = true;
|
|
255
|
-
// Extract the variable qualifier from the entity name so we can use
|
|
256
|
-
// it for the data lookup key later
|
|
257
|
-
variableQualifier = qualifiedKeyMatch[1];
|
|
258
|
-
}
|
|
259
|
-
}
|
|
347
|
+
// Match entity by base name (without generics/args)
|
|
348
|
+
const entityBaseName = entityName.split(/[<(]/)[0];
|
|
349
|
+
const matches =
|
|
350
|
+
entityBaseName === baseMockName || entityName === mockNameParts[0];
|
|
260
351
|
|
|
261
352
|
if (!matches) continue;
|
|
262
353
|
|
|
@@ -295,11 +386,49 @@ export default function constructMockCode(
|
|
|
295
386
|
// However, we still need to remove duplicate function calls that create invalid syntax
|
|
296
387
|
removeDuplicateFunctionCalls(relevantReturnValueSchema);
|
|
297
388
|
dataStructureValue = relevantReturnValueSchema?.[dataStructurePath];
|
|
298
|
-
break;
|
|
389
|
+
break entitySearch;
|
|
299
390
|
}
|
|
300
391
|
}
|
|
301
392
|
}
|
|
302
393
|
|
|
394
|
+
// Check if the entity is used as a function (called with ()) vs an object/namespace.
|
|
395
|
+
// Look for paths in the schema that start with "baseMockName(" or "baseMockName<" indicating function calls.
|
|
396
|
+
// The "<" handles generic type parameters like useLoaderData<T>().
|
|
397
|
+
// Also check dataStructurePath === 'returnValue' which indicates a function return value.
|
|
398
|
+
const entityIsFunction =
|
|
399
|
+
foundEntityWithSignature ||
|
|
400
|
+
dataStructurePath === 'returnValue' ||
|
|
401
|
+
Object.keys(relevantReturnValueSchema ?? {}).some(
|
|
402
|
+
(key) =>
|
|
403
|
+
key.startsWith(`${baseMockName}(`) ||
|
|
404
|
+
key.startsWith(`${baseMockName}<`),
|
|
405
|
+
);
|
|
406
|
+
|
|
407
|
+
// Calculate the data key - use the call signature (mockName) for data access
|
|
408
|
+
// For simple names without parentheses:
|
|
409
|
+
// - Append () ONLY if the entity is a function/hook (detected above)
|
|
410
|
+
// - Don't append () for object/namespace mocks like "supabase"
|
|
411
|
+
if (mockNameIsCallSignature || mockName.includes('(')) {
|
|
412
|
+
dataKey = mockName;
|
|
413
|
+
} else if (entityIsFunction) {
|
|
414
|
+
// Entity is a function/hook - append () to match call signature format
|
|
415
|
+
dataKey = `${mockName}()`;
|
|
416
|
+
} else {
|
|
417
|
+
// Entity is an object/namespace - use bare name as key
|
|
418
|
+
dataKey = mockName;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
// Helper to wrap key in appropriate quotes for computed property access
|
|
422
|
+
// Use single quotes when key contains double quotes to avoid syntax errors
|
|
423
|
+
const quotePropertyKey = (key: string): string => {
|
|
424
|
+
const escaped = key.replace(/\n/g, '\\n');
|
|
425
|
+
if (escaped.includes('"')) {
|
|
426
|
+
// Use single quotes, escaping any single quotes in the key
|
|
427
|
+
return `['${escaped.replace(/'/g, "\\'")}']`;
|
|
428
|
+
}
|
|
429
|
+
return `["${escaped}"]`;
|
|
430
|
+
};
|
|
431
|
+
|
|
303
432
|
// Check if the return value schema only contains function type markers
|
|
304
433
|
// (e.g., "validateInputs()": "function") without actual return data
|
|
305
434
|
// (no functionCallReturnValue entries)
|
|
@@ -328,6 +457,8 @@ export default function constructMockCode(
|
|
|
328
457
|
key.startsWith('signature['),
|
|
329
458
|
).length;
|
|
330
459
|
const args = Array.from({ length: argCount }, (_, i) => `arg${i + 1}`);
|
|
460
|
+
// Always add ...rest to accept extra arguments beyond the signature
|
|
461
|
+
args.push('...rest');
|
|
331
462
|
const argsString = args.join(', ');
|
|
332
463
|
|
|
333
464
|
// Generate empty mock function
|
|
@@ -352,8 +483,38 @@ export default function constructMockCode(
|
|
|
352
483
|
key.startsWith('signature['),
|
|
353
484
|
).length;
|
|
354
485
|
const args = Array.from({ length: argCount }, (_, i) => `arg${i + 1}`);
|
|
486
|
+
// Always add ...rest to accept extra arguments beyond the signature
|
|
487
|
+
args.push('...rest');
|
|
355
488
|
const argsString = args.join(', ');
|
|
356
489
|
|
|
490
|
+
// Check for Higher-Order Component (HOC) pattern:
|
|
491
|
+
// - First argument is a function (component) or unknown (couldn't trace type)
|
|
492
|
+
// - Returns a function
|
|
493
|
+
// HOCs like memo, forwardRef, createContext should return their first argument
|
|
494
|
+
//
|
|
495
|
+
// The return value key can be either:
|
|
496
|
+
// - 'memo()' (clean format)
|
|
497
|
+
// - 'memo(({ value, width }: Props) => { ... })' (full component code format)
|
|
498
|
+
const firstArgIsFunctionOrUnknown =
|
|
499
|
+
signatureSchema['signature[0]'] === 'function' ||
|
|
500
|
+
signatureSchema['signature[0]'] === 'unknown';
|
|
501
|
+
const returnsFunction = relevantReturnValueSchema
|
|
502
|
+
? Object.entries(relevantReturnValueSchema).some(([key, value]) => {
|
|
503
|
+
// Check if key represents a function call that returns a function
|
|
504
|
+
// Key should start with the mock name, contain '(', end with ')', and have value 'function'
|
|
505
|
+
const isFunctionCall =
|
|
506
|
+
key.startsWith(mockName + '(') && key.endsWith(')');
|
|
507
|
+
return isFunctionCall && value === 'function';
|
|
508
|
+
})
|
|
509
|
+
: false;
|
|
510
|
+
|
|
511
|
+
if (firstArgIsFunctionOrUnknown && returnsFunction) {
|
|
512
|
+
// HOC pattern detected - return the first argument
|
|
513
|
+
return `function ${mockName}(${argsString}) {
|
|
514
|
+
return arg1;
|
|
515
|
+
}`;
|
|
516
|
+
}
|
|
517
|
+
|
|
357
518
|
// Generate empty mock function
|
|
358
519
|
return `function ${mockName}(${argsString}) {
|
|
359
520
|
// Empty mock - original function mocked out
|
|
@@ -382,6 +543,99 @@ export default function constructMockCode(
|
|
|
382
543
|
dataStructureValue === 'array' &&
|
|
383
544
|
(dataStructurePath === 'returnValue' || pathDepth <= mockNameParts.length);
|
|
384
545
|
|
|
546
|
+
// OPTIMIZATION: Early return for tuple-returning hooks (useAtom, useState, etc.)
|
|
547
|
+
// These hooks have simple [value, setter] return patterns that don't need the full
|
|
548
|
+
// 9216-key schema processing. Check if this is a tuple-returning hook and generate
|
|
549
|
+
// the mock code directly without iterating over all schema keys.
|
|
550
|
+
if (TUPLE_RETURNING_HOOKS.has(baseMockName) && isFunction) {
|
|
551
|
+
// Check if schema has generic array pattern (indicates tuple return like [value, setter])
|
|
552
|
+
const schemaKeys = Object.keys(relevantReturnValueSchema ?? {});
|
|
553
|
+
const hasGenericArrayInSchema = schemaKeys.some(
|
|
554
|
+
(k) =>
|
|
555
|
+
k.includes('.functionCallReturnValue[]') ||
|
|
556
|
+
k === `${dataKey}.functionCallReturnValue[]` ||
|
|
557
|
+
k === 'returnValue[]',
|
|
558
|
+
);
|
|
559
|
+
|
|
560
|
+
// Check for differentiated tuple indices (e.g., functionCallReturnValue[2], [3]) which would NOT be a standard tuple
|
|
561
|
+
// We only check indices immediately after functionCallReturnValue, not nested indices like signature[2]
|
|
562
|
+
const tupleHasDifferentiatedIndices = schemaKeys.some((k) => {
|
|
563
|
+
// Look for .functionCallReturnValue[N] where N >= 2
|
|
564
|
+
const match = k.match(/\.functionCallReturnValue\[(\d+)\]/);
|
|
565
|
+
if (!match) return false;
|
|
566
|
+
const idx = parseInt(match[1], 10);
|
|
567
|
+
return idx >= 2;
|
|
568
|
+
});
|
|
569
|
+
|
|
570
|
+
const isTupleReturningHook =
|
|
571
|
+
hasGenericArrayInSchema && !tupleHasDifferentiatedIndices;
|
|
572
|
+
|
|
573
|
+
if (isTupleReturningHook) {
|
|
574
|
+
// Find all call patterns for this hook (e.g., useAtom(quoteFilterAtom), useAtom(supplierAtom))
|
|
575
|
+
const hookCallPatterns = Object.keys(relevantReturnValueSchema ?? {})
|
|
576
|
+
.filter((k) => {
|
|
577
|
+
const regex = new RegExp(`^${baseMockName}\\([^)]+\\)$`);
|
|
578
|
+
return regex.test(k);
|
|
579
|
+
})
|
|
580
|
+
.map((k) => {
|
|
581
|
+
const match = k.match(/\(([^)]+)\)/);
|
|
582
|
+
return { key: k, arg: match?.[1] ?? '' };
|
|
583
|
+
});
|
|
584
|
+
|
|
585
|
+
let tupleReturnCode: string;
|
|
586
|
+
if (hookCallPatterns.length > 1) {
|
|
587
|
+
// Multiple patterns - generate conditional dispatch
|
|
588
|
+
const conditions = hookCallPatterns
|
|
589
|
+
.map(
|
|
590
|
+
({ key, arg }) =>
|
|
591
|
+
`if (argLabel === '${arg}' || argStr.includes('${arg}')) {\n return [scenarios().data()?.["${key}"]?.[0] ?? [], () => {}];\n }`,
|
|
592
|
+
)
|
|
593
|
+
.join('\n ');
|
|
594
|
+
const fallbackKey = hookCallPatterns[0]?.key ?? dataKey;
|
|
595
|
+
tupleReturnCode = `(() => {
|
|
596
|
+
// Dynamic dispatch for tuple-returning hook with multiple argument patterns
|
|
597
|
+
const argLabel = args[0]?.debugLabel ?? '';
|
|
598
|
+
const argStr = args[0]?.toString?.() ?? String(args[0] ?? '');
|
|
599
|
+
${conditions}
|
|
600
|
+
return [scenarios().data()?.["${fallbackKey}"]?.[0] ?? [], () => {}];
|
|
601
|
+
})()`;
|
|
602
|
+
} else {
|
|
603
|
+
// Single or no patterns - use dynamic dispatch
|
|
604
|
+
const fallbackKey = hookCallPatterns[0]?.key ?? `${baseMockName}()`;
|
|
605
|
+
tupleReturnCode = `(() => {
|
|
606
|
+
// Dynamic dispatch for tuple-returning hook
|
|
607
|
+
const argLabel = args[0]?.debugLabel ?? '';
|
|
608
|
+
const argStr = args[0]?.toString?.() ?? '';
|
|
609
|
+
const allData = scenarios().data() ?? {};
|
|
610
|
+
if (argLabel) {
|
|
611
|
+
const labelKey = '${baseMockName}(' + argLabel + ')';
|
|
612
|
+
if (allData[labelKey]) {
|
|
613
|
+
return [allData[labelKey]?.[0] ?? [], () => {}];
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
const keys = Object.keys(allData).filter(k => k.startsWith('${baseMockName}('));
|
|
617
|
+
for (const key of keys) {
|
|
618
|
+
const keyArg = key.slice(${baseMockName.length + 1}, -1);
|
|
619
|
+
if (argStr.includes(keyArg)) {
|
|
620
|
+
return [allData[key]?.[0] ?? [], () => {}];
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
return [allData[keys[0] ?? '${fallbackKey}']?.[0] ?? [], () => {}];
|
|
624
|
+
})()`;
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
const safeFunctionName = options?.uniqueFunctionSuffix
|
|
628
|
+
? `${baseMockName}_${options.uniqueFunctionSuffix}`
|
|
629
|
+
: options?.keepOriginalFunctionName
|
|
630
|
+
? baseMockName
|
|
631
|
+
: mockNameIsCallSignature && derivedFunctionName
|
|
632
|
+
? derivedFunctionName
|
|
633
|
+
: baseMockName;
|
|
634
|
+
|
|
635
|
+
return `function ${safeFunctionName}(...args) {\n return ${tupleReturnCode};\n}`;
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
|
|
385
639
|
const returnValueParts: ReturnValuePart = {
|
|
386
640
|
name: dataStructureName,
|
|
387
641
|
isArray: isRootArray,
|
|
@@ -414,26 +668,21 @@ export default function constructMockCode(
|
|
|
414
668
|
// so "useLoaderData<typeof loader>()" becomes "useLoaderData()"
|
|
415
669
|
name = cleanOutTypes(name);
|
|
416
670
|
|
|
417
|
-
// For root data access, use the canonical key
|
|
418
|
-
//
|
|
419
|
-
if (isRootAccess
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
// Format: "variableName <- functionName" (legacy format)
|
|
425
|
-
if (isRootAccess && variableQualifier) {
|
|
426
|
-
const baseName = name.replace(/\(\)$/, '');
|
|
427
|
-
name = `${variableQualifier} <- ${baseName}`;
|
|
671
|
+
// For root data access, use the dataKey (original call signature or canonical key)
|
|
672
|
+
// This preserves the original call signature for LLM clarity
|
|
673
|
+
if (isRootAccess) {
|
|
674
|
+
// For call signature format, use the original mockName as the data key
|
|
675
|
+
// e.g., scenarios().data()?.["useFetcher<User>()"]
|
|
676
|
+
// e.g., scenarios().data()?.["db.select(usersQuery)"]
|
|
677
|
+
return `?.${quotePropertyKey(dataKey)}`;
|
|
428
678
|
}
|
|
429
679
|
|
|
430
680
|
// Only use unquoted array access syntax for pure array indices like [0], [1]
|
|
431
|
-
|
|
432
|
-
if (name.match(/^\[\d+\]$/) && !name.includes(' <- ')) {
|
|
681
|
+
if (name.match(/^\[\d+\]$/)) {
|
|
433
682
|
return `?.${name}`;
|
|
434
683
|
}
|
|
435
684
|
|
|
436
|
-
return
|
|
685
|
+
return `?.${quotePropertyKey(name)}`;
|
|
437
686
|
};
|
|
438
687
|
|
|
439
688
|
const constructDataPaths = () => {
|
|
@@ -501,7 +750,20 @@ export default function constructMockCode(
|
|
|
501
750
|
hasNoReturnData,
|
|
502
751
|
} = returnValue;
|
|
503
752
|
|
|
504
|
-
|
|
753
|
+
// When an array has differentiated indices ([0], [1], etc.), filter out any
|
|
754
|
+
// non-index items from nested. These non-index items come from generic [] paths
|
|
755
|
+
// like [].filter or [].sort, which describe element properties, not array elements.
|
|
756
|
+
// Including them would generate invalid syntax like "sort: ..." inside an array literal.
|
|
757
|
+
const hasDifferentiatedIndices =
|
|
758
|
+
isArray &&
|
|
759
|
+
nested &&
|
|
760
|
+
nested.some((n) => n.name.match(/^\[\d+\]$/) && n.name !== '[0]');
|
|
761
|
+
const filteredNested =
|
|
762
|
+
hasDifferentiatedIndices && nested
|
|
763
|
+
? nested.filter((n) => n.name.match(/^\[\d+\]$/))
|
|
764
|
+
: nested;
|
|
765
|
+
|
|
766
|
+
const nestedContent: (string | undefined)[] = (filteredNested ?? []).map(
|
|
505
767
|
(nestedItem) => {
|
|
506
768
|
const nestedContent = constructReturnValueString(
|
|
507
769
|
nestedItem,
|
|
@@ -585,53 +847,114 @@ export default function constructMockCode(
|
|
|
585
847
|
) {
|
|
586
848
|
levelContentItems.push(...dataPaths.map((path) => `...${path}`));
|
|
587
849
|
}
|
|
588
|
-
|
|
850
|
+
// Filter out nested content that would be invalid as object properties
|
|
851
|
+
// (e.g., bare arrow functions like "() => {...}" without a property name)
|
|
852
|
+
// Only apply this filter when building object content, not array content.
|
|
853
|
+
// Bare arrow functions ARE valid as array elements (like [0] = {...}, [1] = () => {...})
|
|
854
|
+
// Check both isArray (item IS an array) and returnsFunctionArray (item returns an array)
|
|
855
|
+
const inArrayContext = isArray || returnsFunctionArray;
|
|
856
|
+
const validNestedContent = nestedContent.filter((content) => {
|
|
857
|
+
if (!content) return false;
|
|
858
|
+
// Only filter bare arrow functions when NOT in array context
|
|
859
|
+
// In arrays, bare arrow functions are valid elements
|
|
860
|
+
if (!inArrayContext && content.match(/^\s*\([^)]*\)\s*=>/)) {
|
|
861
|
+
return false;
|
|
862
|
+
}
|
|
863
|
+
return true;
|
|
864
|
+
});
|
|
865
|
+
levelContentItems.push(...validNestedContent);
|
|
589
866
|
|
|
590
867
|
let levelContents: string = levelContentItems.filter(Boolean).join(',\n');
|
|
591
868
|
if (returnsFunctionArgs) {
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
869
|
+
// When returnsFunctionArgs is empty [] OR has a single literal string argument,
|
|
870
|
+
// the function returns a callable function (e.g., getTranslate() returns t,
|
|
871
|
+
// where t('key') looks up translations)
|
|
872
|
+
// Generate a dispatch function that looks up keys based on the argument
|
|
873
|
+
//
|
|
874
|
+
// Detect translation-like pattern:
|
|
875
|
+
// - Data path ends with ["('some.literal')"] - a literal string key
|
|
876
|
+
// - This means the mock data has keys like "('common.surveys')": "Surveys"
|
|
877
|
+
// - Exclude ["()"] which is an empty function call (not a translation pattern)
|
|
878
|
+
const dataPath = dataPaths[0];
|
|
879
|
+
// Pattern matches ?.["('...')"] at end of path, but NOT ?.["()"] (empty args)
|
|
880
|
+
const literalKeyPattern = dataPath?.match(/\?\.\["\('.+'\)"\]$/);
|
|
881
|
+
|
|
882
|
+
if (
|
|
883
|
+
!returnsFunctionArray &&
|
|
884
|
+
dataPaths.length === 1 &&
|
|
885
|
+
literalKeyPattern // Only dispatch when there's a literal key pattern
|
|
886
|
+
) {
|
|
887
|
+
// Function returns a function - generate dispatch function
|
|
888
|
+
// Strip the literal key from the path and use dynamic lookup
|
|
889
|
+
const dataPathBase = literalKeyPattern
|
|
890
|
+
? dataPath.replace(/\?\.\["\('.+'\)"\]$/, '')
|
|
891
|
+
: dataPath;
|
|
892
|
+
const funcContents = `return ${dataPathBase}?.[\`('\${arg1}')\`]`;
|
|
893
|
+
levelContents = `(arg1) => {\n${indent(funcContents)}\n}`;
|
|
894
|
+
|
|
895
|
+
if (!isArray) {
|
|
896
|
+
return levelContents;
|
|
608
897
|
}
|
|
609
898
|
} else {
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
if (
|
|
617
|
-
hasNoReturnData ||
|
|
618
|
-
(hasNestedItems && !hasActualNestedContent)
|
|
619
|
-
) {
|
|
899
|
+
const argsString = returnsFunctionArgs
|
|
900
|
+
.map((_, index) => `arg${index + 1}`)
|
|
901
|
+
.join(', ');
|
|
902
|
+
let funcContents = '';
|
|
903
|
+
if (returnsFunctionArray) {
|
|
904
|
+
if (hasNoReturnData) {
|
|
620
905
|
// Function has no return data (only signatures) - return empty array
|
|
621
906
|
funcContents = 'return []';
|
|
622
|
-
} else {
|
|
623
|
-
//
|
|
907
|
+
} else if (levelContents.length === 0 && dataPaths.length === 1) {
|
|
908
|
+
// When returning an array with no nested content, return the data path directly
|
|
909
|
+
// (the data path points to the array in scenario data)
|
|
624
910
|
funcContents = `return ${dataPaths[0]}`;
|
|
911
|
+
} else if (levelContents.length === 0) {
|
|
912
|
+
funcContents = 'return []';
|
|
913
|
+
} else {
|
|
914
|
+
funcContents = `return [\n${indent(levelContents)}\n]`;
|
|
625
915
|
}
|
|
626
916
|
} else {
|
|
627
|
-
|
|
917
|
+
// Check if function has no actual return data (only signatures)
|
|
918
|
+
const hasNestedItems = nested && nested.length > 0;
|
|
919
|
+
const hasActualNestedContent =
|
|
920
|
+
nestedContent.filter(Boolean).length > 0;
|
|
921
|
+
|
|
922
|
+
if (levelContentItems.length === 1 && dataPaths.length === 1) {
|
|
923
|
+
if (
|
|
924
|
+
hasNoReturnData ||
|
|
925
|
+
(hasNestedItems && !hasActualNestedContent)
|
|
926
|
+
) {
|
|
927
|
+
// Function has no return data (only signatures) - return empty array
|
|
928
|
+
funcContents = 'return []';
|
|
929
|
+
} else {
|
|
930
|
+
// Has return data - return data path
|
|
931
|
+
funcContents = `return ${dataPaths[0]}`;
|
|
932
|
+
}
|
|
933
|
+
} else {
|
|
934
|
+
funcContents = `return {\n${indent(levelContents)}\n}`;
|
|
935
|
+
}
|
|
628
936
|
}
|
|
629
|
-
}
|
|
630
937
|
|
|
631
|
-
|
|
938
|
+
levelContents = `(${argsString}) => {\n${indent(funcContents)}\n}`;
|
|
632
939
|
|
|
633
|
-
|
|
634
|
-
|
|
940
|
+
if (!isArray) {
|
|
941
|
+
return levelContents;
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
// For generic arrays of functions WITH nested properties (e.g., functionCallReturnValue[] = "function"
|
|
946
|
+
// with nested .filter, .sort, etc.), the levelContents would be a bare arrow function "() => {...}"
|
|
947
|
+
// that wraps object content. Using this in a .map(({...})) creates invalid syntax like "({ () => {...} })".
|
|
948
|
+
// When isGenericArray is true AND there are nested properties, we're accessing data from the elements,
|
|
949
|
+
// not calling them - so skip the function wrapping.
|
|
950
|
+
// But if there are NO nested properties, keep the wrapper because callers may want to call the elements.
|
|
951
|
+
const hasNonStructuralNestedItems =
|
|
952
|
+
nested &&
|
|
953
|
+
nested.length > 0 &&
|
|
954
|
+
nested.some((n) => !n.name.match(/^\[\d*\]$/));
|
|
955
|
+
if (isGenericArray && hasNonStructuralNestedItems) {
|
|
956
|
+
// Skip the arrow function wrapper - just use the nested content directly
|
|
957
|
+
levelContents = levelContentItems.filter(Boolean).join(',\n');
|
|
635
958
|
}
|
|
636
959
|
}
|
|
637
960
|
|
|
@@ -647,7 +970,123 @@ export default function constructMockCode(
|
|
|
647
970
|
});
|
|
648
971
|
|
|
649
972
|
let returnValueContents = '';
|
|
650
|
-
|
|
973
|
+
|
|
974
|
+
// Check if this is a known tuple-returning hook (useAtom, useState, etc.)
|
|
975
|
+
// These should return [value, setter] tuples, not arrays or data paths
|
|
976
|
+
// Check isGenericArray from current context OR from schema for root level calls
|
|
977
|
+
// (at root level, isGenericArray might not be set yet but the schema contains [] pattern)
|
|
978
|
+
const hasGenericArrayInSchema =
|
|
979
|
+
root &&
|
|
980
|
+
TUPLE_RETURNING_HOOKS.has(baseMockName) &&
|
|
981
|
+
Object.keys(relevantReturnValueSchema ?? {}).some((k) =>
|
|
982
|
+
k.includes('.functionCallReturnValue[]'),
|
|
983
|
+
);
|
|
984
|
+
// Check if there are array indices beyond what a standard 2-element tuple would have
|
|
985
|
+
// For tuple-returning hooks, [0] and [1] are expected (value and setter)
|
|
986
|
+
// Only consider it "differentiated" if there are indices >= 2 (e.g., [2], [3])
|
|
987
|
+
const tupleHasDifferentiatedIndices = nested?.some((n) => {
|
|
988
|
+
const indexMatch = n.name.match(/^\[(\d+)\]$/);
|
|
989
|
+
if (!indexMatch) return false;
|
|
990
|
+
const index = parseInt(indexMatch[1], 10);
|
|
991
|
+
return index >= 2;
|
|
992
|
+
});
|
|
993
|
+
const isTupleReturningHook =
|
|
994
|
+
TUPLE_RETURNING_HOOKS.has(baseMockName) &&
|
|
995
|
+
(isGenericArray || hasGenericArrayInSchema) &&
|
|
996
|
+
!tupleHasDifferentiatedIndices;
|
|
997
|
+
|
|
998
|
+
// Debug logging for tuple-returning hooks
|
|
999
|
+
if (TUPLE_RETURNING_HOOKS.has(baseMockName) && root) {
|
|
1000
|
+
const schemaKeys = Object.keys(relevantReturnValueSchema ?? {});
|
|
1001
|
+
const hasArrayPattern = schemaKeys.some((k) =>
|
|
1002
|
+
k.includes('.functionCallReturnValue[]'),
|
|
1003
|
+
);
|
|
1004
|
+
console.log(
|
|
1005
|
+
`CodeYam: Tuple hook check for ${baseMockName} (root):`,
|
|
1006
|
+
`hasGenericArrayInSchema=${hasGenericArrayInSchema}`,
|
|
1007
|
+
`hasArrayPattern=${hasArrayPattern}`,
|
|
1008
|
+
`tupleHasDifferentiatedIndices=${tupleHasDifferentiatedIndices}`,
|
|
1009
|
+
`isTupleReturningHook=${isTupleReturningHook}`,
|
|
1010
|
+
`schemaKeysSample=${schemaKeys.slice(0, 5).join(', ')}`,
|
|
1011
|
+
);
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
if (isTupleReturningHook) {
|
|
1015
|
+
// Tuple-returning hooks should return [value, setter] tuple
|
|
1016
|
+
// The value is the first element from scenarios data, setter is a no-op
|
|
1017
|
+
// Default to [] when data is undefined to prevent errors like ".includes is not a function"
|
|
1018
|
+
|
|
1019
|
+
// Check if there are multiple call patterns for this hook in the schema
|
|
1020
|
+
// (e.g., useAtom(quoteFilterAtom) and useAtom(supplierAtom))
|
|
1021
|
+
const hookCallPatterns = Object.keys(relevantReturnValueSchema ?? {})
|
|
1022
|
+
.filter((k) => {
|
|
1023
|
+
// Match patterns like "useAtom(someArg)" but not nested paths like "useAtom(x).foo"
|
|
1024
|
+
const regex = new RegExp(`^${baseMockName}\\([^)]+\\)$`);
|
|
1025
|
+
return regex.test(k);
|
|
1026
|
+
})
|
|
1027
|
+
.map((k) => {
|
|
1028
|
+
// Extract the argument from the key like "useAtom(quoteFilterAtom)" -> "quoteFilterAtom"
|
|
1029
|
+
const match = k.match(/\(([^)]+)\)/);
|
|
1030
|
+
return { key: k, arg: match?.[1] ?? '' };
|
|
1031
|
+
});
|
|
1032
|
+
|
|
1033
|
+
if (hookCallPatterns.length > 1) {
|
|
1034
|
+
// Multiple patterns - generate conditional dispatch based on first argument
|
|
1035
|
+
// For Jotai atoms, we use debugLabel; for others, we try to match the argument string
|
|
1036
|
+
const conditions = hookCallPatterns
|
|
1037
|
+
.map(
|
|
1038
|
+
({ key, arg }) =>
|
|
1039
|
+
`if (argLabel === '${arg}' || argStr.includes('${arg}')) {\n return [scenarios().data()?.["${key}"]?.[0] ?? [], () => {}];\n }`,
|
|
1040
|
+
)
|
|
1041
|
+
.join('\n ');
|
|
1042
|
+
|
|
1043
|
+
// Use the first pattern as fallback
|
|
1044
|
+
const fallbackKey = hookCallPatterns[0]?.key ?? dataKey;
|
|
1045
|
+
|
|
1046
|
+
returnValueContents = `(() => {
|
|
1047
|
+
// Dynamic dispatch for tuple-returning hook with multiple argument patterns
|
|
1048
|
+
const argLabel = args[0]?.debugLabel ?? '';
|
|
1049
|
+
const argStr = args[0]?.toString?.() ?? String(args[0] ?? '');
|
|
1050
|
+
${conditions}
|
|
1051
|
+
// Fallback to first pattern
|
|
1052
|
+
return [scenarios().data()?.["${fallbackKey}"]?.[0] ?? [], () => {}];
|
|
1053
|
+
})()`;
|
|
1054
|
+
} else {
|
|
1055
|
+
// Single pattern or no patterns - use dynamic dispatch to handle case where
|
|
1056
|
+
// the mock is used with different atoms than what was captured in the schema.
|
|
1057
|
+
// Use the first argument to construct the data key dynamically.
|
|
1058
|
+
const fallbackKey = hookCallPatterns[0]?.key ?? `${baseMockName}()`;
|
|
1059
|
+
|
|
1060
|
+
returnValueContents = `(() => {
|
|
1061
|
+
// Dynamic dispatch for tuple-returning hook
|
|
1062
|
+
// Try to construct key from argument's debugLabel (Jotai atoms) or toString
|
|
1063
|
+
const argLabel = args[0]?.debugLabel ?? '';
|
|
1064
|
+
const argStr = args[0]?.toString?.() ?? '';
|
|
1065
|
+
const allData = scenarios().data() ?? {};
|
|
1066
|
+
|
|
1067
|
+
// Try to find a matching key using debugLabel first
|
|
1068
|
+
if (argLabel) {
|
|
1069
|
+
const labelKey = '${baseMockName}(' + argLabel + ')';
|
|
1070
|
+
if (allData[labelKey]) {
|
|
1071
|
+
return [allData[labelKey]?.[0] ?? [], () => {}];
|
|
1072
|
+
}
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
// Try to find any matching key that contains part of the argument string
|
|
1076
|
+
const keys = Object.keys(allData).filter(k => k.startsWith('${baseMockName}('));
|
|
1077
|
+
for (const key of keys) {
|
|
1078
|
+
const keyArg = key.slice(${baseMockName.length + 1}, -1);
|
|
1079
|
+
if (argStr.includes(keyArg)) {
|
|
1080
|
+
return [allData[key]?.[0] ?? [], () => {}];
|
|
1081
|
+
}
|
|
1082
|
+
}
|
|
1083
|
+
|
|
1084
|
+
// Fallback to first matching key or default
|
|
1085
|
+
const fallback = keys[0] ?? '${fallbackKey}';
|
|
1086
|
+
return [allData[fallback]?.[0] ?? [], () => {}];
|
|
1087
|
+
})()`;
|
|
1088
|
+
}
|
|
1089
|
+
} else if (
|
|
651
1090
|
!returnsFunctionArgs &&
|
|
652
1091
|
nestedContent.length === 0 &&
|
|
653
1092
|
dataPaths.length === 1
|
|
@@ -685,23 +1124,421 @@ export default function constructMockCode(
|
|
|
685
1124
|
// Get the array base path (without the [0])
|
|
686
1125
|
const arrayBasePath = dataPaths[0].replace(/\?\.\[0\]$/, '');
|
|
687
1126
|
// Replace [0] references with [__idx__] in level contents
|
|
688
|
-
|
|
1127
|
+
let mappedContents = levelContents.replace(
|
|
689
1128
|
/\?\.\[0\]/g,
|
|
690
1129
|
'?.[__idx__]',
|
|
691
1130
|
);
|
|
692
1131
|
// levelContents may already be wrapped in {...} from structural [0] element,
|
|
693
1132
|
// so check if we need to add the wrapper or not
|
|
694
1133
|
const needsWrapper = !mappedContents.trim().startsWith('{');
|
|
1134
|
+
|
|
1135
|
+
// Helper to check if a position is inside a string literal
|
|
1136
|
+
// Returns the end position of the string if inside one, -1 otherwise
|
|
1137
|
+
// Defined here so it's accessible in both needsWrapper branches
|
|
1138
|
+
const skipStringLiteral = (
|
|
1139
|
+
content: string,
|
|
1140
|
+
pos: number,
|
|
1141
|
+
): number => {
|
|
1142
|
+
const char = content[pos];
|
|
1143
|
+
if (char !== '"' && char !== "'" && char !== '`') return -1;
|
|
1144
|
+
// Find the matching closing quote
|
|
1145
|
+
let j = pos + 1;
|
|
1146
|
+
while (j < content.length) {
|
|
1147
|
+
if (content[j] === '\\') {
|
|
1148
|
+
j += 2; // Skip escaped character
|
|
1149
|
+
continue;
|
|
1150
|
+
}
|
|
1151
|
+
if (content[j] === char) {
|
|
1152
|
+
return j + 1; // Return position after closing quote
|
|
1153
|
+
}
|
|
1154
|
+
j++;
|
|
1155
|
+
}
|
|
1156
|
+
return content.length; // Unclosed string, skip to end
|
|
1157
|
+
};
|
|
1158
|
+
|
|
1159
|
+
// Filter out bare arrow functions which are invalid as object properties.
|
|
1160
|
+
// Arrow functions can be multi-line, so we need to match the entire function body, not just the first line.
|
|
1161
|
+
// Pattern: starts with "(args) =>", followed by either:
|
|
1162
|
+
// - A single-line body: "() => expression"
|
|
1163
|
+
// - A multi-line body: "() => { ... }" (with matching braces)
|
|
1164
|
+
// IMPORTANT: Only filter BARE arrow functions (without property names).
|
|
1165
|
+
// "() => {...}" is invalid, but "get: (arg1) => {...}" is valid.
|
|
1166
|
+
// We use a function to properly handle nested braces.
|
|
1167
|
+
// Defined here so it's accessible in both needsWrapper branches
|
|
1168
|
+
const filterOutArrowFunctions = (content: string): string => {
|
|
1169
|
+
const result: string[] = [];
|
|
1170
|
+
let i = 0;
|
|
1171
|
+
while (i < content.length) {
|
|
1172
|
+
// Skip over string literals entirely
|
|
1173
|
+
const stringEnd = skipStringLiteral(content, i);
|
|
1174
|
+
if (stringEnd !== -1) {
|
|
1175
|
+
result.push(content.slice(i, stringEnd));
|
|
1176
|
+
i = stringEnd;
|
|
1177
|
+
continue;
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
// Check if we're at the start of an arrow function (with optional leading whitespace)
|
|
1181
|
+
const arrowMatch = content
|
|
1182
|
+
.slice(i)
|
|
1183
|
+
.match(/^(\s*)\([^)]*\)\s*=>\s*/);
|
|
1184
|
+
if (arrowMatch) {
|
|
1185
|
+
// Check if this is a bare arrow function or a named property with arrow function value
|
|
1186
|
+
// Look back to see if there's a "key:" pattern before this position
|
|
1187
|
+
const before = content.slice(0, i);
|
|
1188
|
+
const beforeTrimmed = before.trim();
|
|
1189
|
+
// Valid patterns where arrow function is NOT bare:
|
|
1190
|
+
// 1. Property value: "key: (arg) => ..." - ends with ':'
|
|
1191
|
+
// 2. Function argument: ".map((arg) => ..." - ends with '('
|
|
1192
|
+
// 3. Method call: "?.map" followed directly by the arrow function
|
|
1193
|
+
// In this case, the '(' is consumed by the arrow function regex match,
|
|
1194
|
+
// so beforeTrimmed ends with the method name (e.g., 'map'), not '('.
|
|
1195
|
+
// We detect this by checking if beforeTrimmed ends with an identifier
|
|
1196
|
+
// that could be a method name (preceded by '.' or '?.').
|
|
1197
|
+
// NOTE: We don't include ',' because "{ prop, () => {} }" is invalid
|
|
1198
|
+
// (can't distinguish function argument from object property context)
|
|
1199
|
+
const isPropertyValue = beforeTrimmed.endsWith(':');
|
|
1200
|
+
const isFunctionArg = beforeTrimmed.endsWith('(');
|
|
1201
|
+
// Check if before ends with a method call pattern like ".map" or "?.map"
|
|
1202
|
+
// The '(' after the method name is consumed by the arrow function regex
|
|
1203
|
+
const isMethodCallArg = /\??\.\w+$/.test(beforeTrimmed);
|
|
1204
|
+
const hasPropertyName =
|
|
1205
|
+
isPropertyValue || isFunctionArg || isMethodCallArg;
|
|
1206
|
+
|
|
1207
|
+
if (!hasPropertyName) {
|
|
1208
|
+
// This is a bare arrow function - filter it out
|
|
1209
|
+
// Found arrow function start, need to find its end
|
|
1210
|
+
const afterArrow = i + arrowMatch[0].length;
|
|
1211
|
+
if (content[afterArrow] === '{') {
|
|
1212
|
+
// Multi-line arrow function - find matching closing brace
|
|
1213
|
+
// Must respect string literals when counting braces
|
|
1214
|
+
let braceCount = 1;
|
|
1215
|
+
let j = afterArrow + 1;
|
|
1216
|
+
while (j < content.length && braceCount > 0) {
|
|
1217
|
+
const strEnd = skipStringLiteral(content, j);
|
|
1218
|
+
if (strEnd !== -1) {
|
|
1219
|
+
j = strEnd;
|
|
1220
|
+
continue;
|
|
1221
|
+
}
|
|
1222
|
+
if (content[j] === '{') braceCount++;
|
|
1223
|
+
if (content[j] === '}') braceCount--;
|
|
1224
|
+
j++;
|
|
1225
|
+
}
|
|
1226
|
+
// Skip past the arrow function
|
|
1227
|
+
i = j;
|
|
1228
|
+
// Only skip trailing comma, keep newlines
|
|
1229
|
+
while (i < content.length && content[i] === ' ') {
|
|
1230
|
+
i++;
|
|
1231
|
+
}
|
|
1232
|
+
if (content[i] === ',') {
|
|
1233
|
+
i++; // Skip the comma after the arrow function
|
|
1234
|
+
}
|
|
1235
|
+
} else {
|
|
1236
|
+
// Single expression arrow function - skip to next comma or newline
|
|
1237
|
+
let j = afterArrow;
|
|
1238
|
+
while (
|
|
1239
|
+
j < content.length &&
|
|
1240
|
+
content[j] !== ',' &&
|
|
1241
|
+
content[j] !== '\n'
|
|
1242
|
+
) {
|
|
1243
|
+
j++;
|
|
1244
|
+
}
|
|
1245
|
+
i = j;
|
|
1246
|
+
if (content[i] === ',') i++; // Skip the comma
|
|
1247
|
+
}
|
|
1248
|
+
continue;
|
|
1249
|
+
}
|
|
1250
|
+
}
|
|
1251
|
+
// Not a bare arrow function, keep this character
|
|
1252
|
+
result.push(content[i]);
|
|
1253
|
+
i++;
|
|
1254
|
+
}
|
|
1255
|
+
return result.join('');
|
|
1256
|
+
};
|
|
1257
|
+
|
|
1258
|
+
// Filter out bare object blocks (e.g., "{ ...spread, props }," without a property name)
|
|
1259
|
+
// These are invalid in object literal context - you need "key: { ... }" not just "{ ... }"
|
|
1260
|
+
// Defined here so it's accessible in both needsWrapper branches
|
|
1261
|
+
// The skipFirstBrace parameter allows the else branch to preserve the outer object
|
|
1262
|
+
const filterOutBareObjects = (
|
|
1263
|
+
content: string,
|
|
1264
|
+
skipFirstBrace = false,
|
|
1265
|
+
): string => {
|
|
1266
|
+
const result: string[] = [];
|
|
1267
|
+
let i = 0;
|
|
1268
|
+
let firstBraceSkipped = false;
|
|
1269
|
+
while (i < content.length) {
|
|
1270
|
+
// Skip over string literals entirely - braces inside strings should not be processed
|
|
1271
|
+
const stringEnd = skipStringLiteral(content, i);
|
|
1272
|
+
if (stringEnd !== -1) {
|
|
1273
|
+
result.push(content.slice(i, stringEnd));
|
|
1274
|
+
i = stringEnd;
|
|
1275
|
+
continue;
|
|
1276
|
+
}
|
|
1277
|
+
|
|
1278
|
+
// Check if we're at a bare object start (newline/comma followed by { without : before it)
|
|
1279
|
+
// Look back to see if there's a colon (property assignment) before this brace
|
|
1280
|
+
const isStartOfLine =
|
|
1281
|
+
i === 0 ||
|
|
1282
|
+
content[i - 1] === '\n' ||
|
|
1283
|
+
content.slice(0, i).trim().endsWith(',');
|
|
1284
|
+
if (content[i] === '{' && isStartOfLine) {
|
|
1285
|
+
// Check if this is actually a bare object (not "key: {")
|
|
1286
|
+
const beforeTrimmed = content.slice(0, i).trim();
|
|
1287
|
+
const isBareObject =
|
|
1288
|
+
beforeTrimmed.endsWith(',') ||
|
|
1289
|
+
beforeTrimmed === '' ||
|
|
1290
|
+
beforeTrimmed.endsWith('(');
|
|
1291
|
+
|
|
1292
|
+
if (isBareObject) {
|
|
1293
|
+
// If skipFirstBrace is true and this is the first bare brace at position 0,
|
|
1294
|
+
// don't filter it - it's the intentional outer object wrapper
|
|
1295
|
+
if (skipFirstBrace && !firstBraceSkipped && i === 0) {
|
|
1296
|
+
firstBraceSkipped = true;
|
|
1297
|
+
result.push(content[i]);
|
|
1298
|
+
i++;
|
|
1299
|
+
continue;
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1302
|
+
// Find matching closing brace, respecting string literals
|
|
1303
|
+
let braceCount = 1;
|
|
1304
|
+
let j = i + 1;
|
|
1305
|
+
while (j < content.length && braceCount > 0) {
|
|
1306
|
+
const strEnd = skipStringLiteral(content, j);
|
|
1307
|
+
if (strEnd !== -1) {
|
|
1308
|
+
j = strEnd;
|
|
1309
|
+
continue;
|
|
1310
|
+
}
|
|
1311
|
+
if (content[j] === '{') braceCount++;
|
|
1312
|
+
if (content[j] === '}') braceCount--;
|
|
1313
|
+
j++;
|
|
1314
|
+
}
|
|
1315
|
+
// Skip past the object
|
|
1316
|
+
i = j;
|
|
1317
|
+
// Skip trailing comma
|
|
1318
|
+
while (i < content.length && content[i] === ' ') {
|
|
1319
|
+
i++;
|
|
1320
|
+
}
|
|
1321
|
+
if (content[i] === ',') {
|
|
1322
|
+
i++;
|
|
1323
|
+
}
|
|
1324
|
+
continue;
|
|
1325
|
+
}
|
|
1326
|
+
}
|
|
1327
|
+
result.push(content[i]);
|
|
1328
|
+
i++;
|
|
1329
|
+
}
|
|
1330
|
+
return result.join('');
|
|
1331
|
+
};
|
|
1332
|
+
|
|
1333
|
+
// Helper to clean up formatting issues after filtering
|
|
1334
|
+
const cleanupContent = (content: string): string => {
|
|
1335
|
+
return (
|
|
1336
|
+
content
|
|
1337
|
+
.replace(/,\s*,/g, ',') // Double commas
|
|
1338
|
+
.replace(/,(\s*\n\s*\})/g, '$1') // Trailing comma before closing brace
|
|
1339
|
+
.replace(/\{\s*\n\s*,/g, '{\n') // Leading comma after opening brace
|
|
1340
|
+
// Remove incomplete .map calls where callback was filtered out
|
|
1341
|
+
// Pattern: ".map" followed by newline/whitespace without "(" for args
|
|
1342
|
+
.replace(/\?\.map(?=\s*[\n\r,}\]])/g, '')
|
|
1343
|
+
.replace(/\.map(?=\s*[\n\r,}\]])/g, '')
|
|
1344
|
+
// Clean up orphan })) sequences (from nested filtered map callbacks)
|
|
1345
|
+
.replace(/\s*\}\)\)\s*\n\s*\}/g, '\n}')
|
|
1346
|
+
.replace(/^\s*\n/gm, '') // Empty lines
|
|
1347
|
+
.trim()
|
|
1348
|
+
);
|
|
1349
|
+
};
|
|
1350
|
+
|
|
695
1351
|
if (needsWrapper) {
|
|
696
|
-
|
|
1352
|
+
// Apply filters to remove invalid content
|
|
1353
|
+
mappedContents = filterOutArrowFunctions(mappedContents);
|
|
1354
|
+
mappedContents = filterOutBareObjects(mappedContents);
|
|
1355
|
+
mappedContents = cleanupContent(mappedContents);
|
|
1356
|
+
|
|
1357
|
+
// If mappedContents is empty after filtering, don't generate .map() at all
|
|
1358
|
+
// Just use the array path directly with spread or as-is
|
|
1359
|
+
// This prevents orphan )) from empty .map() callbacks
|
|
1360
|
+
const cleanedForEmptyCheck = mappedContents
|
|
1361
|
+
.replace(/\s+/g, '')
|
|
1362
|
+
.replace(/,+/g, '');
|
|
1363
|
+
if (cleanedForEmptyCheck.length === 0) {
|
|
1364
|
+
// Content is empty - just return the array directly
|
|
1365
|
+
returnValueContents = arrayBasePath;
|
|
1366
|
+
} else {
|
|
1367
|
+
// Check if mappedContents is just a bare expression (no property names)
|
|
1368
|
+
// A bare expression like "scenarios().data()?.["key"]?.[__idx__]," cannot be
|
|
1369
|
+
// wrapped in ({ }) because it's not a valid object property.
|
|
1370
|
+
// Pattern: content has no ":" that's not inside brackets/parens/strings
|
|
1371
|
+
const hasBareExpression = (() => {
|
|
1372
|
+
const trimmed = mappedContents.trim().replace(/,\s*$/, ''); // Remove trailing comma
|
|
1373
|
+
let depth = 0;
|
|
1374
|
+
let inString = false;
|
|
1375
|
+
let stringChar = '';
|
|
1376
|
+
for (let i = 0; i < trimmed.length; i++) {
|
|
1377
|
+
const char = trimmed[i];
|
|
1378
|
+
if (inString) {
|
|
1379
|
+
if (char === '\\') {
|
|
1380
|
+
i++; // Skip escaped char
|
|
1381
|
+
continue;
|
|
1382
|
+
}
|
|
1383
|
+
if (char === stringChar) {
|
|
1384
|
+
inString = false;
|
|
1385
|
+
}
|
|
1386
|
+
continue;
|
|
1387
|
+
}
|
|
1388
|
+
if (char === '"' || char === "'" || char === '`') {
|
|
1389
|
+
inString = true;
|
|
1390
|
+
stringChar = char;
|
|
1391
|
+
continue;
|
|
1392
|
+
}
|
|
1393
|
+
if (char === '(' || char === '[' || char === '{') {
|
|
1394
|
+
depth++;
|
|
1395
|
+
continue;
|
|
1396
|
+
}
|
|
1397
|
+
if (char === ')' || char === ']' || char === '}') {
|
|
1398
|
+
depth--;
|
|
1399
|
+
continue;
|
|
1400
|
+
}
|
|
1401
|
+
// Found a colon at depth 0 = has property name
|
|
1402
|
+
if (char === ':' && depth === 0) {
|
|
1403
|
+
return false;
|
|
1404
|
+
}
|
|
1405
|
+
}
|
|
1406
|
+
return true;
|
|
1407
|
+
})();
|
|
1408
|
+
|
|
1409
|
+
if (hasBareExpression) {
|
|
1410
|
+
// Content is just an expression - return it directly without object wrapper
|
|
1411
|
+
const trimmedContent = mappedContents
|
|
1412
|
+
.trim()
|
|
1413
|
+
.replace(/,\s*$/, '');
|
|
1414
|
+
returnValueContents = `${arrayBasePath}?.map((__item__, __idx__) => (\n${indent(trimmedContent)}\n))`;
|
|
1415
|
+
} else {
|
|
1416
|
+
// When generating object-wrapped .map(), ensure original item data is preserved.
|
|
1417
|
+
// If no data spread was included (e.g., because this is a plain array property,
|
|
1418
|
+
// not a function return), add ...__item__ to spread the original item properties.
|
|
1419
|
+
// Without this, the .map() would create new objects with only nested function
|
|
1420
|
+
// properties, losing data like filePath, frontmatter, body, etc.
|
|
1421
|
+
const hasDataSpread =
|
|
1422
|
+
mappedContents.includes('...scenarios()') ||
|
|
1423
|
+
mappedContents.includes('...__item__');
|
|
1424
|
+
if (!hasDataSpread) {
|
|
1425
|
+
mappedContents = `...__item__,\n${mappedContents}`;
|
|
1426
|
+
}
|
|
1427
|
+
returnValueContents = `${arrayBasePath}?.map((__item__, __idx__) => ({\n${indent(mappedContents)}\n}))`;
|
|
1428
|
+
}
|
|
1429
|
+
} // Close the empty content check else block
|
|
697
1430
|
} else {
|
|
1431
|
+
// Content already starts with '{'. Check if there are additional properties after the inner object.
|
|
1432
|
+
// If so, we need to merge them INTO the object, not leave them outside.
|
|
1433
|
+
// Pattern: "{ ...spread, props },\nfilter: ...,\nsort: ..."
|
|
1434
|
+
// Should become: "{ ...spread, props, filter: ..., sort: ... }"
|
|
1435
|
+
const trimmed = mappedContents.trim();
|
|
1436
|
+
|
|
1437
|
+
// Find first }, at depth 0 that is NOT inside a string literal
|
|
1438
|
+
// This prevents splitting keys like ?.["useQuery({ id }, { enabled })"]
|
|
1439
|
+
// and also prevents finding }, inside nested arrow functions
|
|
1440
|
+
const findBraceCommaOutsideStrings = (
|
|
1441
|
+
content: string,
|
|
1442
|
+
): number => {
|
|
1443
|
+
let i = 0;
|
|
1444
|
+
let depth = 0; // Track brace depth to find the outer object's },
|
|
1445
|
+
while (i < content.length - 1) {
|
|
1446
|
+
// Skip over string literals
|
|
1447
|
+
const strEnd = skipStringLiteral(content, i);
|
|
1448
|
+
if (strEnd !== -1) {
|
|
1449
|
+
i = strEnd;
|
|
1450
|
+
continue;
|
|
1451
|
+
}
|
|
1452
|
+
// Track brace depth
|
|
1453
|
+
if (content[i] === '{') {
|
|
1454
|
+
depth++;
|
|
1455
|
+
i++;
|
|
1456
|
+
continue;
|
|
1457
|
+
}
|
|
1458
|
+
// Check for }, pattern at depth 1 (the outer object level)
|
|
1459
|
+
// We're looking for the outer object's closing brace, which is at depth 1
|
|
1460
|
+
// (we started at depth 0, opened { at depth 0 -> 1)
|
|
1461
|
+
if (content[i] === '}') {
|
|
1462
|
+
depth--;
|
|
1463
|
+
if (
|
|
1464
|
+
depth === 0 &&
|
|
1465
|
+
i + 1 < content.length &&
|
|
1466
|
+
content[i + 1] === ','
|
|
1467
|
+
) {
|
|
1468
|
+
return i;
|
|
1469
|
+
}
|
|
1470
|
+
}
|
|
1471
|
+
i++;
|
|
1472
|
+
}
|
|
1473
|
+
return -1;
|
|
1474
|
+
};
|
|
1475
|
+
|
|
1476
|
+
const firstBraceEnd = findBraceCommaOutsideStrings(trimmed);
|
|
1477
|
+
if (firstBraceEnd !== -1) {
|
|
1478
|
+
// Found pattern "{ ... }," followed by more content
|
|
1479
|
+
// Extract the inner object and the trailing properties
|
|
1480
|
+
const innerObject = trimmed.slice(0, firstBraceEnd);
|
|
1481
|
+
const trailingContent = trimmed.slice(firstBraceEnd + 2).trim();
|
|
1482
|
+
if (trailingContent) {
|
|
1483
|
+
// Merge trailing properties into the inner object
|
|
1484
|
+
mappedContents = `${innerObject},\n${trailingContent}\n}`;
|
|
1485
|
+
}
|
|
1486
|
+
}
|
|
1487
|
+
// Even when content starts with {, we need to filter out invalid properties inside
|
|
1488
|
+
// (arrow functions and bare objects that were generated from the schema)
|
|
1489
|
+
// Pass skipFirstBrace=true because the content's outer { is the intentional wrapper
|
|
1490
|
+
mappedContents = filterOutArrowFunctions(mappedContents);
|
|
1491
|
+
mappedContents = filterOutBareObjects(mappedContents, true);
|
|
1492
|
+
mappedContents = cleanupContent(mappedContents);
|
|
1493
|
+
// Same as needsWrapper branch: ensure item data is preserved in .map()
|
|
1494
|
+
const hasDataSpreadInner =
|
|
1495
|
+
mappedContents.includes('...scenarios()') ||
|
|
1496
|
+
mappedContents.includes('...__item__');
|
|
1497
|
+
if (!hasDataSpreadInner && mappedContents.trim().length > 0) {
|
|
1498
|
+
// Insert ...__item__ after the opening brace
|
|
1499
|
+
mappedContents = mappedContents.replace(
|
|
1500
|
+
/^\s*\{/,
|
|
1501
|
+
'{\n...__item__,',
|
|
1502
|
+
);
|
|
1503
|
+
}
|
|
698
1504
|
returnValueContents = `${arrayBasePath}?.map((__item__, __idx__) => (\n${indent(mappedContents)}\n))`;
|
|
699
1505
|
}
|
|
700
1506
|
} else {
|
|
701
1507
|
returnValueContents = `[\n${indent(levelContents)}\n]`;
|
|
702
1508
|
}
|
|
703
1509
|
} else {
|
|
704
|
-
|
|
1510
|
+
// When we have a single data path and nested content that creates an object structure,
|
|
1511
|
+
// and we're NOT at the root level, we need to handle the case where the parent data
|
|
1512
|
+
// value is null or undefined. Without this check, `{ ...null, prop: null?.["prop"] }`
|
|
1513
|
+
// creates `{ prop: undefined }` instead of `null`, causing errors like
|
|
1514
|
+
// "Cannot read properties of undefined (reading 'some')" when code does
|
|
1515
|
+
// data?.prop.some(...) because data is an object with prop: undefined, not null.
|
|
1516
|
+
// We only apply this to non-root cases because root-level mocks are expected to exist.
|
|
1517
|
+
// We also skip structural elements (like [0] inside arrays) because the null check
|
|
1518
|
+
// syntax doesn't work inside .map() callbacks where structural elements are used.
|
|
1519
|
+
// We also skip array index elements ([0], [1], etc.) because they represent tuple/array
|
|
1520
|
+
// elements, not properties that could be null.
|
|
1521
|
+
// We also only apply this when we're inside a function return value context - i.e.,
|
|
1522
|
+
// when the data path contains a function call pattern like ?.["someFunction(...)"].
|
|
1523
|
+
// This prevents adding null checks to intermediate objects in chains like supabase.auth.
|
|
1524
|
+
const hasNestedContent = nestedContent.filter(Boolean).length > 0;
|
|
1525
|
+
const isArrayIndexElement = name.match(/^\[\d*\]$/);
|
|
1526
|
+
// Check if data path contains a function call pattern, indicating we're inside a function return value
|
|
1527
|
+
const isInsideFunctionReturnValue =
|
|
1528
|
+
dataPaths.length === 1 &&
|
|
1529
|
+
dataPaths[0].match(/\?\.\["\w+\([^"]*\)"\]/);
|
|
1530
|
+
if (
|
|
1531
|
+
!root &&
|
|
1532
|
+
!returnValue.isStructural &&
|
|
1533
|
+
!isArrayIndexElement &&
|
|
1534
|
+
isInsideFunctionReturnValue &&
|
|
1535
|
+
hasNestedContent
|
|
1536
|
+
) {
|
|
1537
|
+
// Wrap with null check: if parent is null/undefined, return it directly; otherwise create object
|
|
1538
|
+
returnValueContents = `${dataPaths[0]} == null ? ${dataPaths[0]} : {\n${indent(levelContents)}\n}`;
|
|
1539
|
+
} else {
|
|
1540
|
+
returnValueContents = `{\n${indent(levelContents)}\n}`;
|
|
1541
|
+
}
|
|
705
1542
|
}
|
|
706
1543
|
}
|
|
707
1544
|
|
|
@@ -800,14 +1637,29 @@ export default function constructMockCode(
|
|
|
800
1637
|
content = `${cleanOutTypes(name)}: ${isAsyncFunction ? 'async ' : ''}(${argsString}) => {\n${indent(funcContents)}\n}`;
|
|
801
1638
|
} else {
|
|
802
1639
|
// No argument variants - use existing behavior
|
|
803
|
-
|
|
1640
|
+
// But if there's nested content, we need to include it in the return object
|
|
1641
|
+
// (similar to how argument variant branches handle this at line 1070-1072)
|
|
1642
|
+
const hasNestedContent = validNestedContent.length > 0;
|
|
1643
|
+
let funcReturnContents: string;
|
|
1644
|
+
if (hasNestedContent && levelContentItems.length > 1) {
|
|
1645
|
+
// Include both spread and nested content in the return
|
|
1646
|
+
funcReturnContents = `{\n${indent(levelContents)}\n}`;
|
|
1647
|
+
} else {
|
|
1648
|
+
funcReturnContents = returnValueContents;
|
|
1649
|
+
}
|
|
1650
|
+
const funcContents = `return ${funcReturnContents}`;
|
|
804
1651
|
content = `${cleanOutTypes(name)}: ${isAsyncFunction ? 'async ' : ''}(${argsString}) => {\n${indent(funcContents)}\n}`;
|
|
805
1652
|
}
|
|
806
1653
|
} else {
|
|
807
1654
|
if (!isValidKey(name)) {
|
|
808
1655
|
return;
|
|
809
1656
|
} else if (name.match(/\[\d*\]/)) {
|
|
1657
|
+
// Numeric array index like [0], [1] - can be used as computed property
|
|
810
1658
|
content = returnValueContents;
|
|
1659
|
+
} else if (name.match(/^\[[a-zA-Z_]\w*\]$/)) {
|
|
1660
|
+
// Variable-based index like [currentItemIndex] - must be quoted string key
|
|
1661
|
+
// Otherwise JavaScript would try to evaluate the variable name
|
|
1662
|
+
content = `"${safeString(name)}": ${returnValueContents}`;
|
|
811
1663
|
} else {
|
|
812
1664
|
content = `${safeString(name)}: ${returnValueContents}`;
|
|
813
1665
|
}
|
|
@@ -822,34 +1674,91 @@ export default function constructMockCode(
|
|
|
822
1674
|
};
|
|
823
1675
|
|
|
824
1676
|
// Create the return value structure
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
1677
|
+
// OPTIMIZATION: Filter keys to only those starting with baseMockName before sorting.
|
|
1678
|
+
// This dramatically reduces processing time for large schemas (e.g., 9216 keys -> ~100 relevant keys).
|
|
1679
|
+
// Without this filter, the loop would call splitOutsideParenthesesAndArrays on every key
|
|
1680
|
+
// even though most are filtered out later by the baseMockName check.
|
|
1681
|
+
const allSchemaKeys = Object.keys(relevantReturnValueSchema ?? {});
|
|
1682
|
+
const relevantKeys = allSchemaKeys.filter((key) => {
|
|
1683
|
+
// Fast prefix check - key must start with baseMockName followed by ( or < or .
|
|
1684
|
+
// This matches: "useAtom()", "useAtom<T>()", "useAtom.something", but not "useAtomValue()"
|
|
1685
|
+
if (key === baseMockName) return true;
|
|
1686
|
+
if (key.startsWith(baseMockName + '(')) return true;
|
|
1687
|
+
if (key.startsWith(baseMockName + '<')) return true;
|
|
1688
|
+
if (key.startsWith(baseMockName + '.')) return true;
|
|
1689
|
+
// Also include 'returnValue' paths which are normalized later
|
|
1690
|
+
if (
|
|
1691
|
+
key === 'returnValue' ||
|
|
1692
|
+
key.startsWith('returnValue.') ||
|
|
1693
|
+
key.startsWith('returnValue[')
|
|
1694
|
+
)
|
|
1695
|
+
return true;
|
|
1696
|
+
return false;
|
|
1697
|
+
});
|
|
1698
|
+
|
|
1699
|
+
const schemaKeyCount = relevantKeys.length;
|
|
1700
|
+
const sortedKeys = relevantKeys.sort((a: string, b: string) => {
|
|
1701
|
+
const aParts = splitOutsideParenthesesAndArrays(a);
|
|
1702
|
+
const bParts = splitOutsideParenthesesAndArrays(b);
|
|
1703
|
+
|
|
1704
|
+
const maxLength = Math.max(aParts.length, bParts.length);
|
|
1705
|
+
for (let i = 0; i < maxLength; ++i) {
|
|
1706
|
+
const aPart = aParts[i];
|
|
1707
|
+
const bPart = bParts[i];
|
|
1708
|
+
|
|
1709
|
+
if (!aPart) return -1;
|
|
1710
|
+
if (!bPart) return 1;
|
|
1711
|
+
|
|
1712
|
+
if (aPart === bPart) continue;
|
|
1713
|
+
|
|
1714
|
+
const aName = aPart.split('(')[0];
|
|
1715
|
+
const bName = bPart.split('(')[0];
|
|
1716
|
+
|
|
1717
|
+
if (aName !== bName) {
|
|
1718
|
+
return aName.localeCompare(bName);
|
|
1719
|
+
} else {
|
|
1720
|
+
return aPart.localeCompare(bPart);
|
|
1721
|
+
}
|
|
1722
|
+
}
|
|
842
1723
|
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
1724
|
+
return 0;
|
|
1725
|
+
});
|
|
1726
|
+
|
|
1727
|
+
// OPTIMIZATION: Pre-compute prefix indexes for O(1) lookups instead of O(n) scans.
|
|
1728
|
+
// This reduces complexity from O(n²) to O(n) for large schemas (9k+ keys).
|
|
1729
|
+
//
|
|
1730
|
+
// 1. extendedReturnValuePrefixes: Set of all path prefixes that have a .functionCallReturnValue extension
|
|
1731
|
+
// Used by hasExtendedFunctionCallReturnValue check at line ~1754
|
|
1732
|
+
// 2. functionCallsWithReturnValue: Set of function call paths where .functionCallReturnValue IMMEDIATELY follows
|
|
1733
|
+
// Used by hasProperFunctionCallPath check at line ~1787
|
|
1734
|
+
// IMPORTANT: Only includes paths where the function call is directly followed by .functionCallReturnValue
|
|
1735
|
+
// e.g., "a.b().functionCallReturnValue" -> adds "a.b()" but NOT "a" even if "a" ends with ")"
|
|
1736
|
+
const extendedReturnValuePrefixes = new Set<string>();
|
|
1737
|
+
const functionCallsWithReturnValue = new Set<string>();
|
|
1738
|
+
|
|
1739
|
+
for (const k of relevantKeys) {
|
|
1740
|
+
const parts = splitOutsideParenthesesAndArrays(k);
|
|
1741
|
+
const returnValueIndex = parts.findIndex((part) =>
|
|
1742
|
+
part.startsWith(RETURN_VALUE),
|
|
1743
|
+
);
|
|
1744
|
+
if (returnValueIndex !== -1) {
|
|
1745
|
+
// Add all prefixes of k up to (but not including) functionCallReturnValue
|
|
1746
|
+
const prefix = joinParenthesesAndArrays(parts.slice(0, returnValueIndex));
|
|
1747
|
+
extendedReturnValuePrefixes.add(prefix);
|
|
1748
|
+
|
|
1749
|
+
// ONLY add to functionCallsWithReturnValue if functionCallReturnValue IMMEDIATELY follows
|
|
1750
|
+
if (prefix.endsWith(')')) {
|
|
1751
|
+
functionCallsWithReturnValue.add(prefix);
|
|
848
1752
|
}
|
|
849
1753
|
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
1754
|
+
// Also add intermediate prefixes for nested paths to extendedReturnValuePrefixes
|
|
1755
|
+
// This helps hasExtendedFunctionCallReturnValue which checks key + '.'
|
|
1756
|
+
for (let i = 1; i < returnValueIndex; i++) {
|
|
1757
|
+
const partialPrefix = joinParenthesesAndArrays(parts.slice(0, i));
|
|
1758
|
+
extendedReturnValuePrefixes.add(partialPrefix);
|
|
1759
|
+
}
|
|
1760
|
+
}
|
|
1761
|
+
}
|
|
853
1762
|
|
|
854
1763
|
for (const key of sortedKeys) {
|
|
855
1764
|
const value = relevantReturnValueSchema[key];
|
|
@@ -884,8 +1793,8 @@ export default function constructMockCode(
|
|
|
884
1793
|
}
|
|
885
1794
|
}
|
|
886
1795
|
|
|
887
|
-
//
|
|
888
|
-
//
|
|
1796
|
+
// Compare against baseMockName (without generics/args), not the full mockName
|
|
1797
|
+
// e.g., for "useFetcher<User>()", baseMockName is "useFetcher"
|
|
889
1798
|
if (parts[0].split('(')[0] !== baseMockName) continue;
|
|
890
1799
|
|
|
891
1800
|
// Include paths with functionCallReturnValue OR function-typed paths that need mocking
|
|
@@ -907,9 +1816,10 @@ export default function constructMockCode(
|
|
|
907
1816
|
// nested inside (e.g., methods on array elements passed as arguments).
|
|
908
1817
|
if (hasSignaturePath) continue;
|
|
909
1818
|
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
1819
|
+
// OPTIMIZATION: Use pre-computed index instead of O(n) scan
|
|
1820
|
+
// Old code: Object.keys(relevantReturnValueSchema).some((k) => k.startsWith(key + '.') && k.includes('.functionCallReturnValue'))
|
|
1821
|
+
const hasExtendedFunctionCallReturnValue =
|
|
1822
|
+
extendedReturnValuePrefixes.has(key);
|
|
913
1823
|
|
|
914
1824
|
// Skip JSX components - they look like function calls (e.g., Context.Provider())
|
|
915
1825
|
// but they're React components used in JSX, not functions that need mocking
|
|
@@ -938,11 +1848,10 @@ export default function constructMockCode(
|
|
|
938
1848
|
const functionCallPath = joinParenthesesAndArrays(
|
|
939
1849
|
parts.slice(0, i + 1),
|
|
940
1850
|
);
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
);
|
|
1851
|
+
// OPTIMIZATION: Use pre-computed index instead of O(n) scan
|
|
1852
|
+
// Old code: Object.keys(relevantReturnValueSchema).some((k) => k.startsWith(functionCallPath + '.functionCallReturnValue'))
|
|
1853
|
+
const hasProperFunctionCallPath =
|
|
1854
|
+
functionCallsWithReturnValue.has(functionCallPath);
|
|
946
1855
|
if (hasProperFunctionCallPath) {
|
|
947
1856
|
// Skip this path - the .functionCallReturnValue path will handle it correctly
|
|
948
1857
|
shouldSkipKey = true;
|
|
@@ -1001,6 +1910,17 @@ export default function constructMockCode(
|
|
|
1001
1910
|
const nextIsArray = !!nextPart?.match(/^\[\d*\]/);
|
|
1002
1911
|
const isDifferentiatedArray = !!part?.match(/^\[\d+\]/);
|
|
1003
1912
|
const nextIsDifferentiatedArray = !!nextPart?.match(/^\[\d+\]/);
|
|
1913
|
+
|
|
1914
|
+
// Variable index patterns like [currentItemIndex] or [targetIndex] indicate array access
|
|
1915
|
+
// but don't represent actual data structure - they're markers from variable-based index tracking.
|
|
1916
|
+
// Skip them AND all remaining parts to avoid creating spurious nested structure that breaks array iteration.
|
|
1917
|
+
// The remaining parts (e.g., .missing_attributes) describe properties of array elements, which are
|
|
1918
|
+
// already handled by the generic [] accessor path.
|
|
1919
|
+
const isVariableIndex = !!part?.match(/^\[[a-zA-Z_]\w*\]$/);
|
|
1920
|
+
if (isVariableIndex) {
|
|
1921
|
+
// Break out of the loop entirely - don't process any remaining parts
|
|
1922
|
+
break;
|
|
1923
|
+
}
|
|
1004
1924
|
// Find the correct value for the current part being processed
|
|
1005
1925
|
let partValue = value; // default to the final value
|
|
1006
1926
|
if (isFunctionCallReturnValue(part) && nextIsArray) {
|
|
@@ -1108,7 +2028,52 @@ export default function constructMockCode(
|
|
|
1108
2028
|
}
|
|
1109
2029
|
}
|
|
1110
2030
|
} else {
|
|
1111
|
-
|
|
2031
|
+
// Before setting returnsFunctionArgs on the parent (for generic [] = function),
|
|
2032
|
+
// check if there are specific array indices (like [0], [1]) that are NOT functions.
|
|
2033
|
+
// If so, don't set returnsFunctionArgs because those specific indices take precedence.
|
|
2034
|
+
// This prevents adding ["()"] to paths like [0] when [0] is 'unknown' but [] is 'function'.
|
|
2035
|
+
//
|
|
2036
|
+
// Use parts.slice(0, i + 1) to get the current path INCLUDING functionCallReturnValue.
|
|
2037
|
+
// For example, if parts = ['useAtom()','functionCallReturnValue','[]']
|
|
2038
|
+
// and i = 1, we want to check 'useAtom().functionCallReturnValue[0]' etc.
|
|
2039
|
+
const arrayContainerPath = joinParenthesesAndArrays(
|
|
2040
|
+
parts.slice(0, i + 1),
|
|
2041
|
+
);
|
|
2042
|
+
|
|
2043
|
+
const hasNonFunctionSpecificIndices = Object.entries(
|
|
2044
|
+
relevantReturnValueSchema,
|
|
2045
|
+
).some(([k, v]) => {
|
|
2046
|
+
// Look for paths like "arrayContainerPath[0]", "arrayContainerPath[1]" etc.
|
|
2047
|
+
const indexMatch = k.match(
|
|
2048
|
+
new RegExp(
|
|
2049
|
+
`^${arrayContainerPath.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\[(\\d+)\\]$`,
|
|
2050
|
+
),
|
|
2051
|
+
);
|
|
2052
|
+
// If found and it's NOT a function type, we have a conflict
|
|
2053
|
+
return (
|
|
2054
|
+
indexMatch &&
|
|
2055
|
+
!['function', 'async-function'].includes(v as string)
|
|
2056
|
+
);
|
|
2057
|
+
});
|
|
2058
|
+
|
|
2059
|
+
// Also check if [] has nested object properties (like [].filter, [].name)
|
|
2060
|
+
// If so, [] items are objects with properties, not pure functions to be called
|
|
2061
|
+
// This handles cases where the schema shows [].filter = object but doesn't
|
|
2062
|
+
// have explicit [0] entries
|
|
2063
|
+
const genericArrayPath = `${arrayContainerPath}[]`;
|
|
2064
|
+
const hasNestedProperties = Object.keys(
|
|
2065
|
+
relevantReturnValueSchema,
|
|
2066
|
+
).some((k) => {
|
|
2067
|
+
// Check for paths like "arrayContainerPath[].propertyName" (not [].())
|
|
2068
|
+
return (
|
|
2069
|
+
k.startsWith(genericArrayPath + '.') &&
|
|
2070
|
+
!k.startsWith(genericArrayPath + '.(')
|
|
2071
|
+
);
|
|
2072
|
+
});
|
|
2073
|
+
|
|
2074
|
+
if (!hasNonFunctionSpecificIndices && !hasNestedProperties) {
|
|
2075
|
+
returnValueSection.returnsFunctionArgs = [];
|
|
2076
|
+
}
|
|
1112
2077
|
}
|
|
1113
2078
|
}
|
|
1114
2079
|
}
|
|
@@ -1133,7 +2098,8 @@ export default function constructMockCode(
|
|
|
1133
2098
|
}
|
|
1134
2099
|
// If the next part is an object with nested content, continue processing
|
|
1135
2100
|
// This handles paths like functionCallReturnValue.selectedOptions.elementOptions[]
|
|
1136
|
-
|
|
2101
|
+
// Also handles union types like 'array | undefined' or 'object | undefined'
|
|
2102
|
+
if (nextValue?.includes('object') || nextValue?.includes('array')) {
|
|
1137
2103
|
continue;
|
|
1138
2104
|
}
|
|
1139
2105
|
}
|
|
@@ -1287,7 +2253,14 @@ export default function constructMockCode(
|
|
|
1287
2253
|
relevantPart.isGenericArray = true;
|
|
1288
2254
|
}
|
|
1289
2255
|
|
|
1290
|
-
if
|
|
2256
|
+
// Check if there are remaining parts after functionCallReturnValue that need processing
|
|
2257
|
+
// (e.g., data properties like useQuery().functionCallReturnValue.data)
|
|
2258
|
+
const hasRemainingPartsAfterReturnValue =
|
|
2259
|
+
nextPart &&
|
|
2260
|
+
(isFunctionCallReturnValue(nextPart) ||
|
|
2261
|
+
(isFunctionCallReturnValue(parts[i]) && i < parts.length - 1));
|
|
2262
|
+
|
|
2263
|
+
if (!hasNestedFunction && !hasRemainingPartsAfterReturnValue) {
|
|
1291
2264
|
// Before breaking, check if this function returns an array
|
|
1292
2265
|
// by looking for a functionCallReturnValue: 'array' entry in the schema
|
|
1293
2266
|
if (relevantPart && part.endsWith(')')) {
|
|
@@ -1319,6 +2292,7 @@ export default function constructMockCode(
|
|
|
1319
2292
|
|
|
1320
2293
|
if (mockNameParts.length > 1) {
|
|
1321
2294
|
const originalLib = `${mockNameParts[0]}__cyOriginal`;
|
|
2295
|
+
const skipOriginalSpread = options?.skipOriginalSpread;
|
|
1322
2296
|
|
|
1323
2297
|
const subPart = (
|
|
1324
2298
|
parts: string[],
|
|
@@ -1330,7 +2304,9 @@ export default function constructMockCode(
|
|
|
1330
2304
|
|
|
1331
2305
|
const partContents = isLast
|
|
1332
2306
|
? contents
|
|
1333
|
-
:
|
|
2307
|
+
: skipOriginalSpread
|
|
2308
|
+
? subPart(parts, originalLib)
|
|
2309
|
+
: `...${originalLib}.${part},\n${subPart(parts, originalLib)}`;
|
|
1334
2310
|
|
|
1335
2311
|
let code = `${part}: {\n${indent(partContents)}\n}`;
|
|
1336
2312
|
|
|
@@ -1344,29 +2320,31 @@ export default function constructMockCode(
|
|
|
1344
2320
|
return code;
|
|
1345
2321
|
};
|
|
1346
2322
|
|
|
1347
|
-
const returnParts =
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
2323
|
+
const returnParts = skipOriginalSpread
|
|
2324
|
+
? [subPart(mockNameParts.slice(1), originalLib)]
|
|
2325
|
+
: [
|
|
2326
|
+
`...${mockNameParts[0]}__cyOriginal`,
|
|
2327
|
+
subPart(mockNameParts.slice(1), originalLib),
|
|
2328
|
+
];
|
|
1351
2329
|
|
|
1352
|
-
return `const ${mockNameParts[0]} = {\n${indent(returnParts.join(',\n'))}\n};`;
|
|
2330
|
+
return `const ${mockNameParts[0]} = {\n${indent(returnParts.filter(Boolean).join(',\n'))}\n};`;
|
|
1353
2331
|
} else if (isFunction) {
|
|
1354
2332
|
// For headers() and cookies() from next/headers, add common iterator methods
|
|
1355
2333
|
// These are needed when the mock is passed to functions that use .entries(), .keys(), etc.
|
|
1356
2334
|
// (e.g., Object.fromEntries(headers.entries()) in buildLegacyHeaders)
|
|
1357
2335
|
const needsIteratorMethods =
|
|
1358
|
-
|
|
2336
|
+
baseMockName === 'headers' || baseMockName === 'cookies';
|
|
1359
2337
|
let enhancedContents = contents;
|
|
1360
2338
|
if (needsIteratorMethods && contents.trim().startsWith('{')) {
|
|
1361
2339
|
// Add iterator methods that operate on the scenario data
|
|
1362
|
-
// Use
|
|
1363
|
-
const
|
|
2340
|
+
// Use the dataKey (original call signature or canonical key)
|
|
2341
|
+
const quotedDataKey = quotePropertyKey(dataKey);
|
|
1364
2342
|
const iteratorMethods = `,
|
|
1365
|
-
entries: () => Object.entries(scenarios().data()
|
|
1366
|
-
keys: () => Object.keys(scenarios().data()
|
|
1367
|
-
values: () => Object.values(scenarios().data()
|
|
1368
|
-
forEach: (fn) => Object.entries(scenarios().data()
|
|
1369
|
-
has: (key) => Object.prototype.hasOwnProperty.call(scenarios().data()
|
|
2343
|
+
entries: () => Object.entries(scenarios().data()?.${quotedDataKey} || {}),
|
|
2344
|
+
keys: () => Object.keys(scenarios().data()?.${quotedDataKey} || {}),
|
|
2345
|
+
values: () => Object.values(scenarios().data()?.${quotedDataKey} || {}),
|
|
2346
|
+
forEach: (fn) => Object.entries(scenarios().data()?.${quotedDataKey} || {}).forEach(([k, v]) => fn(v, k)),
|
|
2347
|
+
has: (key) => Object.prototype.hasOwnProperty.call(scenarios().data()?.${quotedDataKey} || {}, key)`;
|
|
1370
2348
|
// Insert before the closing brace (handle trailing whitespace)
|
|
1371
2349
|
enhancedContents = contents.replace(/\}\s*$/, iteratorMethods + '\n}');
|
|
1372
2350
|
}
|
|
@@ -1377,32 +2355,42 @@ export default function constructMockCode(
|
|
|
1377
2355
|
// `new ClassName("arg")` wouldn't create the expected instance.
|
|
1378
2356
|
// For Error subclasses (detected by name ending in "Error"), extend Error for proper error handling.
|
|
1379
2357
|
if (entityType === 'class') {
|
|
1380
|
-
const isErrorSubclass =
|
|
1381
|
-
const baseClass = isErrorSubclass ? 'Error' : 'Object';
|
|
2358
|
+
const isErrorSubclass = baseMockName.endsWith('Error');
|
|
1382
2359
|
const superCall = isErrorSubclass ? 'super(message);' : '';
|
|
1383
2360
|
const nameAssignment = isErrorSubclass
|
|
1384
|
-
? `this.name = '${
|
|
2361
|
+
? `this.name = '${baseMockName}';`
|
|
1385
2362
|
: '';
|
|
1386
|
-
// Use
|
|
1387
|
-
const
|
|
2363
|
+
// Use the safe function name for the class definition
|
|
2364
|
+
const className = mockNameIsCallSignature
|
|
2365
|
+
? derivedFunctionName
|
|
2366
|
+
: baseMockName;
|
|
1388
2367
|
|
|
1389
|
-
return `class ${
|
|
2368
|
+
return `class ${className}${isErrorSubclass ? ' extends Error' : ''} {
|
|
1390
2369
|
constructor(message) {
|
|
1391
2370
|
${superCall}
|
|
1392
2371
|
${nameAssignment}
|
|
1393
|
-
Object.assign(this, scenarios().data()
|
|
2372
|
+
Object.assign(this, scenarios().data()?.${quotePropertyKey(dataKey)} || {});
|
|
1394
2373
|
}
|
|
1395
2374
|
}`;
|
|
1396
2375
|
}
|
|
1397
2376
|
|
|
1398
|
-
//
|
|
1399
|
-
//
|
|
1400
|
-
//
|
|
1401
|
-
//
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
2377
|
+
// Generate safe function name:
|
|
2378
|
+
// 1. For call signatures: use derivedFunctionName
|
|
2379
|
+
// e.g., "useFetcher<User>()" becomes "useFetcher_User"
|
|
2380
|
+
// e.g., "db.select(usersQuery)" becomes "db_select_usersQuery"
|
|
2381
|
+
// 2. With uniqueFunctionSuffix option: append suffix for unique naming
|
|
2382
|
+
// e.g., baseMockName = "useFetcher", suffix = "entityDiffFetcher" -> "useFetcher_entityDiffFetcher"
|
|
2383
|
+
// 3. EXCEPTION: When keepOriginalFunctionName is true (for single-call cases), use the base name
|
|
2384
|
+
let safeFunctionName: string;
|
|
2385
|
+
if (options?.keepOriginalFunctionName) {
|
|
2386
|
+
safeFunctionName = baseMockName;
|
|
2387
|
+
} else if (options?.uniqueFunctionSuffix) {
|
|
2388
|
+
safeFunctionName = `${baseMockName}_${options.uniqueFunctionSuffix}`;
|
|
2389
|
+
} else if (mockNameIsCallSignature && derivedFunctionName) {
|
|
2390
|
+
safeFunctionName = derivedFunctionName;
|
|
2391
|
+
} else {
|
|
2392
|
+
safeFunctionName = baseMockName;
|
|
2393
|
+
}
|
|
1406
2394
|
|
|
1407
2395
|
// Check if this function returns a function (detected by double-call pattern: mockName(args)())
|
|
1408
2396
|
// This happens when the schema has keys like "wrapThrows(() => JSON.parse(savedFilters))()"
|
|
@@ -1441,21 +2429,56 @@ export default function constructMockCode(
|
|
|
1441
2429
|
return false;
|
|
1442
2430
|
});
|
|
1443
2431
|
|
|
2432
|
+
// Use ...args to accept any number of arguments - prevents TypeScript errors
|
|
2433
|
+
// like "Expected 0 arguments, but got X" when caller passes arguments
|
|
1444
2434
|
// For higher-order functions, wrap the return in an arrow function
|
|
1445
2435
|
// so that mockFunc(arg)() works correctly (outer call returns a function, inner call gets the data)
|
|
1446
2436
|
const returnValue = isHigherOrderFunction
|
|
1447
|
-
? `() => ${
|
|
1448
|
-
:
|
|
1449
|
-
|
|
1450
|
-
|
|
2437
|
+
? `() => (${enhancedContents})`
|
|
2438
|
+
: enhancedContents;
|
|
2439
|
+
|
|
2440
|
+
// Inline the return value directly in the function to avoid module-level const
|
|
2441
|
+
// that would be evaluated before scenario context is ready
|
|
2442
|
+
// Add fallback for simple data path returns to prevent undefined errors (e.g., createTheme)
|
|
2443
|
+
// Only add fallback if returnValue is a simple data accessor (starts with scenarios().data())
|
|
2444
|
+
// and doesn't already have nested structure (object literal, array, or method chains like .map())
|
|
2445
|
+
const isSimpleDataPath =
|
|
2446
|
+
returnValue.startsWith('scenarios().data()') &&
|
|
2447
|
+
!returnValue.trim().startsWith('{') &&
|
|
2448
|
+
!returnValue.trim().startsWith('[') &&
|
|
2449
|
+
!returnValue.includes('.map('); // Exclude method chains
|
|
2450
|
+
const safeReturnValue = isSimpleDataPath
|
|
2451
|
+
? `${returnValue} ?? {}`
|
|
2452
|
+
: returnValue;
|
|
2453
|
+
const refName = `_${safeFunctionName}Ref`;
|
|
2454
|
+
const assignment = `${refName}.current = ${safeReturnValue};`;
|
|
2455
|
+
const ifBlock = `if (!${refName}.current) {\n${indent(assignment)}\n}`;
|
|
2456
|
+
const body = `${ifBlock}\nreturn ${refName}.current;`;
|
|
2457
|
+
|
|
2458
|
+
return [
|
|
2459
|
+
`// PATCHED: memoize to return stable reference (prevents infinite useEffect re-triggers)`,
|
|
2460
|
+
`const ${refName} = {`,
|
|
2461
|
+
` current: null,`,
|
|
2462
|
+
`};`,
|
|
2463
|
+
`${isRootAsyncFunction ? 'async ' : ''}function ${safeFunctionName}(...args) {`,
|
|
2464
|
+
indent(body),
|
|
2465
|
+
`}`,
|
|
2466
|
+
].join('\n');
|
|
1451
2467
|
} else {
|
|
1452
|
-
//
|
|
1453
|
-
//
|
|
1454
|
-
//
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
2468
|
+
// Generate safe const name:
|
|
2469
|
+
// 1. For call signatures: use derivedFunctionName
|
|
2470
|
+
// 2. With uniqueFunctionSuffix option: append suffix for unique naming
|
|
2471
|
+
// 3. EXCEPTION: When keepOriginalFunctionName is true (for single-call cases), use the base name
|
|
2472
|
+
let safeName: string;
|
|
2473
|
+
if (options?.keepOriginalFunctionName) {
|
|
2474
|
+
safeName = baseMockName;
|
|
2475
|
+
} else if (options?.uniqueFunctionSuffix) {
|
|
2476
|
+
safeName = `${baseMockName}_${options.uniqueFunctionSuffix}`;
|
|
2477
|
+
} else if (mockNameIsCallSignature && derivedFunctionName) {
|
|
2478
|
+
safeName = derivedFunctionName;
|
|
2479
|
+
} else {
|
|
2480
|
+
safeName = baseMockName;
|
|
2481
|
+
}
|
|
1459
2482
|
|
|
1460
2483
|
// Get any jsx-component properties that need to be preserved from the original
|
|
1461
2484
|
const jsxProperties = getJsxComponentProperties(
|