@codeyam/codeyam-cli 0.1.0-staging.8aea589 → 0.1.0-staging.bbe4da9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/analyzer-template/.build-info.json +7 -7
- package/analyzer-template/log.txt +3 -3
- package/analyzer-template/package.json +8 -7
- package/analyzer-template/packages/ai/index.ts +6 -2
- package/analyzer-template/packages/ai/package.json +2 -2
- package/analyzer-template/packages/ai/scripts/ai-test-matrix.mjs +424 -0
- package/analyzer-template/packages/ai/src/lib/analyzeScope.ts +24 -0
- package/analyzer-template/packages/ai/src/lib/astScopes/astScopeAnalyzer.ts +6 -16
- package/analyzer-template/packages/ai/src/lib/astScopes/methodSemantics.ts +197 -0
- package/analyzer-template/packages/ai/src/lib/astScopes/paths.ts +28 -2
- package/analyzer-template/packages/ai/src/lib/astScopes/processExpression.ts +145 -4
- package/analyzer-template/packages/ai/src/lib/checkAllAttributes.ts +1 -3
- package/analyzer-template/packages/ai/src/lib/dataStructure/ScopeDataStructure.ts +1877 -542
- package/analyzer-template/packages/ai/src/lib/dataStructure/equivalencyManagers/FunctionCallManager.ts +138 -0
- package/analyzer-template/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/ReactFrameworkManager.ts +1 -1
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/BatchSchemaProcessor.ts +139 -0
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/DebugTracer.ts +224 -0
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/PathManager.ts +203 -0
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/README.md +294 -0
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/ScopeTreeManager.ts +161 -0
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/VisitedTracker.ts +235 -0
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/cleanNonObjectFunctions.ts +64 -1
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.ts +14 -6
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/selectBestValue.ts +70 -0
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/uniqueIdUtils.ts +113 -0
- package/analyzer-template/packages/ai/src/lib/gatherRelevantDependentKeyAttributes.ts +36 -0
- package/analyzer-template/packages/ai/src/lib/generateChangesEntityDocumentation.ts +20 -2
- package/analyzer-template/packages/ai/src/lib/generateChangesEntityScenarioData.ts +56 -160
- package/analyzer-template/packages/ai/src/lib/generateChangesEntityScenarios.ts +79 -265
- package/analyzer-template/packages/ai/src/lib/generateEntityDocumentation.ts +16 -2
- package/analyzer-template/packages/ai/src/lib/generateEntityKeyAttributes.ts +32 -8
- package/analyzer-template/packages/ai/src/lib/generateEntityScenarioData.ts +53 -154
- package/analyzer-template/packages/ai/src/lib/generateEntityScenarios.ts +84 -254
- package/analyzer-template/packages/ai/src/lib/generateStatementAnalysis.ts +48 -71
- package/analyzer-template/packages/ai/src/lib/getConditionalUsagesFromCode.ts +27 -6
- package/analyzer-template/packages/ai/src/lib/getLLMCallStats.ts +0 -14
- package/analyzer-template/packages/ai/src/lib/modelInfo.ts +15 -0
- package/analyzer-template/packages/ai/src/lib/promptGenerators/gatherAttributesMap.ts +42 -4
- package/analyzer-template/packages/ai/src/lib/promptGenerators/generateChangesEntityDocumentationGenerator.ts +8 -33
- package/analyzer-template/packages/ai/src/lib/promptGenerators/generateChangesEntityScenarioDataGenerator.ts +54 -62
- package/analyzer-template/packages/ai/src/lib/promptGenerators/generateChangesEntityScenariosGenerator.ts +93 -109
- package/analyzer-template/packages/ai/src/lib/promptGenerators/generateEntityDocumentationGenerator.ts +8 -27
- package/analyzer-template/packages/ai/src/lib/promptGenerators/generateEntityScenarioDataGenerator.ts +33 -38
- package/analyzer-template/packages/ai/src/lib/promptGenerators/generateEntityScenariosGenerator.ts +30 -30
- package/analyzer-template/packages/ai/src/lib/types/index.ts +2 -0
- package/analyzer-template/packages/ai/src/lib/worker/SerializableDataStructure.ts +41 -0
- package/analyzer-template/packages/analyze/src/lib/FileAnalyzer.ts +47 -8
- package/analyzer-template/packages/analyze/src/lib/asts/nodes/getNodeType.ts +1 -1
- package/analyzer-template/packages/analyze/src/lib/asts/nodes/index.ts +2 -1
- package/analyzer-template/packages/analyze/src/lib/asts/sourceFiles/getAllExportedNodes.ts +4 -2
- package/analyzer-template/packages/analyze/src/lib/asts/sourceFiles/getAllExports.ts +5 -3
- package/analyzer-template/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.ts +8 -10
- package/analyzer-template/packages/analyze/src/lib/files/analyze/analyzeEntities.ts +6 -1
- package/analyzer-template/packages/analyze/src/lib/files/analyze/gatherEntityMap.ts +8 -6
- package/analyzer-template/packages/analyze/src/lib/files/analyze/trackEntityCircularDependencies.ts +5 -13
- package/analyzer-template/packages/analyze/src/lib/files/analyzeChange.ts +34 -15
- package/analyzer-template/packages/analyze/src/lib/files/analyzeEntity.ts +17 -3
- package/analyzer-template/packages/analyze/src/lib/files/analyzeInitial.ts +35 -16
- package/analyzer-template/packages/analyze/src/lib/files/analyzeRemixRoute.ts +21 -33
- package/analyzer-template/packages/analyze/src/lib/files/getImportedExports.ts +75 -10
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.ts +26 -0
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateDataStructure.ts +7 -1
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateKeyAttributes.ts +9 -1
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateScenarioData.ts +6 -1
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateScenarios.ts +9 -1
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.ts +15 -7
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/mergeValidatedDataStructures.ts +12 -2
- package/analyzer-template/packages/aws/dist/src/lib/s3/getPresignedUrl.d.ts +23 -0
- package/analyzer-template/packages/aws/dist/src/lib/s3/getPresignedUrl.d.ts.map +1 -0
- package/analyzer-template/packages/aws/dist/src/lib/s3/getPresignedUrl.js +30 -0
- package/analyzer-template/packages/aws/dist/src/lib/s3/getPresignedUrl.js.map +1 -0
- package/analyzer-template/packages/aws/package.json +5 -4
- package/analyzer-template/packages/aws/s3/index.ts +4 -0
- package/analyzer-template/packages/aws/src/lib/s3/getPresignedUrl.ts +62 -0
- package/analyzer-template/packages/generate/src/lib/componentScenarioPage/componentScenarioPageNext.ts +28 -21
- package/analyzer-template/packages/generate/src/lib/componentScenarioPage/componentScenarioPageRemix.ts +18 -11
- package/analyzer-template/packages/generate/src/lib/scenarioComponent.ts +6 -3
- 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 +28 -21
- 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/componentScenarioPageRemix.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/componentScenarioPageRemix.js +18 -11
- package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/componentScenarioPageRemix.js.map +1 -1
- package/analyzer-template/packages/github/dist/generate/src/lib/scenarioComponent.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/generate/src/lib/scenarioComponent.js +5 -3
- package/analyzer-template/packages/github/dist/generate/src/lib/scenarioComponent.js.map +1 -1
- package/analyzer-template/packages/github/dist/supabase/src/lib/kysely/db.d.ts +2 -0
- package/analyzer-template/packages/github/dist/supabase/src/lib/kysely/db.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/supabase/src/lib/kysely/db.js +3 -0
- package/analyzer-template/packages/github/dist/supabase/src/lib/kysely/db.js.map +1 -1
- package/analyzer-template/packages/github/dist/supabase/src/lib/kysely/tableRelations.d.ts +2 -0
- package/analyzer-template/packages/github/dist/supabase/src/lib/kysely/tableRelations.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/supabase/src/lib/kysely/tables/debugReportsTable.d.ts +37 -0
- package/analyzer-template/packages/github/dist/supabase/src/lib/kysely/tables/debugReportsTable.d.ts.map +1 -0
- package/analyzer-template/packages/github/dist/supabase/src/lib/kysely/tables/debugReportsTable.js +27 -0
- package/analyzer-template/packages/github/dist/supabase/src/lib/kysely/tables/debugReportsTable.js.map +1 -0
- package/analyzer-template/packages/github/dist/supabase/src/lib/scenarioToDb.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/supabase/src/lib/scenarioToDb.js +1 -1
- package/analyzer-template/packages/github/dist/supabase/src/lib/scenarioToDb.js.map +1 -1
- package/analyzer-template/packages/github/dist/utils/index.d.ts +2 -0
- package/analyzer-template/packages/github/dist/utils/index.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/utils/index.js +2 -0
- package/analyzer-template/packages/github/dist/utils/index.js.map +1 -1
- package/analyzer-template/packages/github/dist/utils/src/lib/Semaphore.d.ts +25 -0
- package/analyzer-template/packages/github/dist/utils/src/lib/Semaphore.d.ts.map +1 -0
- package/analyzer-template/packages/github/dist/utils/src/lib/Semaphore.js +40 -0
- package/analyzer-template/packages/github/dist/utils/src/lib/Semaphore.js.map +1 -0
- package/analyzer-template/packages/github/dist/utils/src/lib/applyUniversalMocks.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/utils/src/lib/applyUniversalMocks.js +39 -5
- package/analyzer-template/packages/github/dist/utils/src/lib/applyUniversalMocks.js.map +1 -1
- package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/getNextRoutePath.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/getNextRoutePath.js +2 -1
- package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/getNextRoutePath.js.map +1 -1
- package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/getRemixRoutePath.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/getRemixRoutePath.js +2 -1
- package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/getRemixRoutePath.js.map +1 -1
- package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/nextRouteFileNameToRoute.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/nextRouteFileNameToRoute.js +2 -1
- package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/nextRouteFileNameToRoute.js.map +1 -1
- package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/remixRouteFileNameToRoute.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/remixRouteFileNameToRoute.js +1 -0
- package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/remixRouteFileNameToRoute.js.map +1 -1
- package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/sanitizeNextRouteSegments.d.ts +12 -0
- package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/sanitizeNextRouteSegments.d.ts.map +1 -0
- package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/sanitizeNextRouteSegments.js +32 -0
- package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/sanitizeNextRouteSegments.js.map +1 -0
- package/analyzer-template/packages/github/dist/utils/src/lib/lightweightEntityExtractor.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/utils/src/lib/lightweightEntityExtractor.js +17 -0
- package/analyzer-template/packages/github/dist/utils/src/lib/lightweightEntityExtractor.js.map +1 -1
- package/analyzer-template/packages/supabase/src/lib/kysely/db.ts +6 -0
- package/analyzer-template/packages/supabase/src/lib/kysely/tableRelations.ts +3 -0
- package/analyzer-template/packages/supabase/src/lib/kysely/tables/debugReportsTable.ts +61 -0
- package/analyzer-template/packages/supabase/src/lib/scenarioToDb.ts +1 -0
- package/analyzer-template/packages/ui-components/src/scenario-editor/components/DataItemEditor.tsx +1 -1
- package/analyzer-template/packages/utils/dist/utils/index.d.ts +2 -0
- package/analyzer-template/packages/utils/dist/utils/index.d.ts.map +1 -1
- package/analyzer-template/packages/utils/dist/utils/index.js +2 -0
- package/analyzer-template/packages/utils/dist/utils/index.js.map +1 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/Semaphore.d.ts +25 -0
- package/analyzer-template/packages/utils/dist/utils/src/lib/Semaphore.d.ts.map +1 -0
- package/analyzer-template/packages/utils/dist/utils/src/lib/Semaphore.js +40 -0
- package/analyzer-template/packages/utils/dist/utils/src/lib/Semaphore.js.map +1 -0
- package/analyzer-template/packages/utils/dist/utils/src/lib/applyUniversalMocks.d.ts.map +1 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/applyUniversalMocks.js +39 -5
- package/analyzer-template/packages/utils/dist/utils/src/lib/applyUniversalMocks.js.map +1 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/getNextRoutePath.d.ts.map +1 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/getNextRoutePath.js +2 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/getNextRoutePath.js.map +1 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/getRemixRoutePath.d.ts.map +1 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/getRemixRoutePath.js +2 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/getRemixRoutePath.js.map +1 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/nextRouteFileNameToRoute.d.ts.map +1 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/nextRouteFileNameToRoute.js +2 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/nextRouteFileNameToRoute.js.map +1 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/remixRouteFileNameToRoute.d.ts.map +1 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/remixRouteFileNameToRoute.js +1 -0
- package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/remixRouteFileNameToRoute.js.map +1 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/sanitizeNextRouteSegments.d.ts +12 -0
- package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/sanitizeNextRouteSegments.d.ts.map +1 -0
- package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/sanitizeNextRouteSegments.js +32 -0
- package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/sanitizeNextRouteSegments.js.map +1 -0
- package/analyzer-template/packages/utils/dist/utils/src/lib/lightweightEntityExtractor.d.ts.map +1 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/lightweightEntityExtractor.js +17 -0
- package/analyzer-template/packages/utils/dist/utils/src/lib/lightweightEntityExtractor.js.map +1 -1
- package/analyzer-template/packages/utils/index.ts +2 -0
- package/analyzer-template/packages/utils/src/lib/Semaphore.ts +42 -0
- package/analyzer-template/packages/utils/src/lib/applyUniversalMocks.ts +46 -7
- package/analyzer-template/packages/utils/src/lib/frameworks/getNextRoutePath.ts +2 -1
- package/analyzer-template/packages/utils/src/lib/frameworks/getRemixRoutePath.ts +2 -1
- package/analyzer-template/packages/utils/src/lib/frameworks/nextRouteFileNameToRoute.ts +2 -1
- package/analyzer-template/packages/utils/src/lib/frameworks/remixRouteFileNameToRoute.ts +1 -0
- package/analyzer-template/packages/utils/src/lib/frameworks/sanitizeNextRouteSegments.ts +33 -0
- package/analyzer-template/packages/utils/src/lib/lightweightEntityExtractor.ts +16 -0
- package/analyzer-template/project/constructMockCode.ts +199 -9
- package/analyzer-template/project/reconcileMockDataKeys.ts +13 -0
- package/analyzer-template/project/runMultiScenarioServer.ts +0 -4
- package/analyzer-template/project/runScenarioServer.ts +0 -4
- package/analyzer-template/project/start.ts +1 -11
- package/analyzer-template/project/startScenarioCapture.ts +24 -0
- package/analyzer-template/project/startServer.ts +50 -70
- package/analyzer-template/project/trackGeneratedFiles.ts +41 -0
- package/analyzer-template/project/writeMockDataTsx.ts +191 -7
- package/analyzer-template/project/writeScenarioComponents.ts +643 -63
- package/analyzer-template/project/writeUniversalMocks.ts +66 -8
- package/analyzer-template/scripts/postbuild.cjs +12 -1
- package/background/src/lib/virtualized/project/constructMockCode.js +183 -11
- package/background/src/lib/virtualized/project/constructMockCode.js.map +1 -1
- package/background/src/lib/virtualized/project/reconcileMockDataKeys.js +12 -0
- package/background/src/lib/virtualized/project/reconcileMockDataKeys.js.map +1 -1
- package/background/src/lib/virtualized/project/runMultiScenarioServer.js +0 -3
- package/background/src/lib/virtualized/project/runMultiScenarioServer.js.map +1 -1
- package/background/src/lib/virtualized/project/start.js +1 -8
- package/background/src/lib/virtualized/project/start.js.map +1 -1
- package/background/src/lib/virtualized/project/startScenarioCapture.js +18 -0
- package/background/src/lib/virtualized/project/startScenarioCapture.js.map +1 -1
- package/background/src/lib/virtualized/project/startServer.js +40 -68
- package/background/src/lib/virtualized/project/startServer.js.map +1 -1
- package/background/src/lib/virtualized/project/trackGeneratedFiles.js +30 -0
- package/background/src/lib/virtualized/project/trackGeneratedFiles.js.map +1 -0
- package/background/src/lib/virtualized/project/writeMockDataTsx.js +156 -6
- package/background/src/lib/virtualized/project/writeMockDataTsx.js.map +1 -1
- package/background/src/lib/virtualized/project/writeScenarioComponents.js +433 -41
- package/background/src/lib/virtualized/project/writeScenarioComponents.js.map +1 -1
- package/background/src/lib/virtualized/project/writeUniversalMocks.js +56 -7
- package/background/src/lib/virtualized/project/writeUniversalMocks.js.map +1 -1
- package/codeyam-cli/src/cli.js +6 -0
- package/codeyam-cli/src/cli.js.map +1 -1
- package/codeyam-cli/src/codeyam-cli.js +0 -0
- package/codeyam-cli/src/commands/debug.js +222 -0
- package/codeyam-cli/src/commands/debug.js.map +1 -0
- package/codeyam-cli/src/commands/init.js +4 -23
- package/codeyam-cli/src/commands/init.js.map +1 -1
- package/codeyam-cli/src/commands/report.js +102 -0
- package/codeyam-cli/src/commands/report.js.map +1 -0
- package/codeyam-cli/src/commands/setup-sandbox.js +165 -0
- package/codeyam-cli/src/commands/setup-sandbox.js.map +1 -0
- package/codeyam-cli/src/commands/test-startup.js +14 -5
- package/codeyam-cli/src/commands/test-startup.js.map +1 -1
- package/codeyam-cli/src/utils/__tests__/cleanupAnalysisFiles.test.js +6 -6
- package/codeyam-cli/src/utils/__tests__/cleanupAnalysisFiles.test.js.map +1 -1
- package/codeyam-cli/src/utils/__tests__/setupClaudeCodeSettings.test.js +8 -0
- package/codeyam-cli/src/utils/__tests__/setupClaudeCodeSettings.test.js.map +1 -1
- package/codeyam-cli/src/utils/analysisRunner.js +2 -1
- package/codeyam-cli/src/utils/analysisRunner.js.map +1 -1
- package/codeyam-cli/src/utils/analyzer.js +24 -2
- package/codeyam-cli/src/utils/analyzer.js.map +1 -1
- package/codeyam-cli/src/utils/cleanupAnalysisFiles.js +2 -2
- package/codeyam-cli/src/utils/cleanupAnalysisFiles.js.map +1 -1
- package/codeyam-cli/src/utils/generateReport.js +219 -0
- package/codeyam-cli/src/utils/generateReport.js.map +1 -0
- package/codeyam-cli/src/utils/install-skills.js +7 -0
- package/codeyam-cli/src/utils/install-skills.js.map +1 -1
- package/codeyam-cli/src/utils/queue/__tests__/job.pidTracking.test.js +1 -0
- package/codeyam-cli/src/utils/queue/__tests__/job.pidTracking.test.js.map +1 -1
- package/codeyam-cli/src/utils/queue/job.js +10 -5
- package/codeyam-cli/src/utils/queue/job.js.map +1 -1
- package/codeyam-cli/src/utils/sandbox.js +190 -0
- package/codeyam-cli/src/utils/sandbox.js.map +1 -0
- package/codeyam-cli/src/utils/setupClaudeCodeSettings.js +4 -0
- package/codeyam-cli/src/utils/setupClaudeCodeSettings.js.map +1 -1
- package/codeyam-cli/src/utils/webappDetection.js +2 -1
- package/codeyam-cli/src/utils/webappDetection.js.map +1 -1
- package/codeyam-cli/src/webserver/app/lib/database.js +50 -2
- package/codeyam-cli/src/webserver/app/lib/database.js.map +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/EntityTypeIcon-Dp_FTAs1.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/InteractivePreview-TlHocYno.js +26 -0
- package/codeyam-cli/src/webserver/build/client/assets/LibraryFunctionPreview-CVMmGuIc.js +3 -0
- package/codeyam-cli/src/webserver/build/client/assets/{LogViewer-BKKG1s2B.js → LogViewer-JkfQ-VaI.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/ReportIssueModal-Cqce0_KG.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/SafeScreenshot-BrMAP1nP.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/ScenarioPreview-Bi-__7HT.js +6 -0
- package/codeyam-cli/src/webserver/build/client/assets/ScenarioViewer-XmIpHcLJ.js +5 -0
- package/codeyam-cli/src/webserver/build/client/assets/_index-BmfhU6CA.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/activity.(_tab)-Dm8lM73z.js +10 -0
- package/codeyam-cli/src/webserver/build/client/assets/api.generate-report-l0sNRNKZ.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/chart-column-kA4jn9if.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/chunk-WWGJGFF6-CgXbbZRx.js +26 -0
- package/codeyam-cli/src/webserver/build/client/assets/circle-check-B2oHQ-zo.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/clock-BAfbP_iK.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/codeyam-name-logo-CvKwUgHo.svg +9 -0
- package/codeyam-cli/src/webserver/build/client/assets/createLucideIcon-BBYuR56H.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/dev.empty-BgPXZbm0.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{entity._sha._-BHiWkb_W.js → entity._sha._-BkoAXaOa.js} +10 -10
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.create-scenario-Bj5GHkhb.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.edit._scenarioId-eW5z9AyZ.js +5 -0
- package/codeyam-cli/src/webserver/build/client/assets/entityStatus-C5Okl18j.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{entityVersioning-Bk_YB1jM.js → entityVersioning-CU_Lchhc.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/entry.client-B9tSboXM.js +5 -0
- package/codeyam-cli/src/webserver/build/client/assets/file-text-18aYHZGd.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/files-Df79EyEb.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/git-CDEwTVH_.js +12 -0
- package/codeyam-cli/src/webserver/build/client/assets/globals-DXRB6jBc.css +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/html2canvas-pro.esm-XQCGvadH.js +5 -0
- package/codeyam-cli/src/webserver/build/client/assets/index-_LjBsTxX.js +8 -0
- package/codeyam-cli/src/webserver/build/client/assets/loader-circle-D_EGChhq.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/manifest-3e0ffbcc.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/root-CGyT4J4b.js +16 -0
- package/codeyam-cli/src/webserver/build/client/assets/settings-CEPbAsom.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/settings-R8QF_mHX.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/simulations-B_PXvFom.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/triangle-alert-BthANBVv.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{useLastLogLine-Lumm1t01.js → useLastLogLine-Blr5oZDE.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/useReportContext-CANr3QJ5.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/useToast-Bbf4Hokd.js +1 -0
- package/codeyam-cli/src/webserver/build/server/assets/index-vf1FETCO.js +1 -0
- package/codeyam-cli/src/webserver/build/server/assets/server-build-B5s58TvB.js +169 -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 +1 -1
- package/codeyam-cli/src/webserver/server.js.map +1 -1
- package/codeyam-cli/templates/codeyam-setup-skill.md +70 -85
- package/codeyam-cli/templates/debug-command.md +125 -0
- package/package.json +9 -11
- package/packages/ai/index.js +2 -3
- package/packages/ai/index.js.map +1 -1
- package/packages/ai/src/lib/analyzeScope.js +13 -0
- package/packages/ai/src/lib/analyzeScope.js.map +1 -1
- package/packages/ai/src/lib/astScopes/astScopeAnalyzer.js +6 -15
- package/packages/ai/src/lib/astScopes/astScopeAnalyzer.js.map +1 -1
- package/packages/ai/src/lib/astScopes/methodSemantics.js +134 -0
- package/packages/ai/src/lib/astScopes/methodSemantics.js.map +1 -1
- package/packages/ai/src/lib/astScopes/paths.js +28 -3
- package/packages/ai/src/lib/astScopes/paths.js.map +1 -1
- package/packages/ai/src/lib/astScopes/processExpression.js +123 -3
- package/packages/ai/src/lib/astScopes/processExpression.js.map +1 -1
- package/packages/ai/src/lib/checkAllAttributes.js +1 -3
- package/packages/ai/src/lib/checkAllAttributes.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js +1358 -396
- package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/equivalencyManagers/FunctionCallManager.js +137 -1
- package/packages/ai/src/lib/dataStructure/equivalencyManagers/FunctionCallManager.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/ReactFrameworkManager.js +1 -1
- package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/ReactFrameworkManager.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/helpers/BatchSchemaProcessor.js +112 -0
- package/packages/ai/src/lib/dataStructure/helpers/BatchSchemaProcessor.js.map +1 -0
- package/packages/ai/src/lib/dataStructure/helpers/DebugTracer.js +176 -0
- package/packages/ai/src/lib/dataStructure/helpers/DebugTracer.js.map +1 -0
- package/packages/ai/src/lib/dataStructure/helpers/PathManager.js +178 -0
- package/packages/ai/src/lib/dataStructure/helpers/PathManager.js.map +1 -0
- package/packages/ai/src/lib/dataStructure/helpers/ScopeTreeManager.js +138 -0
- package/packages/ai/src/lib/dataStructure/helpers/ScopeTreeManager.js.map +1 -0
- package/packages/ai/src/lib/dataStructure/helpers/VisitedTracker.js +199 -0
- package/packages/ai/src/lib/dataStructure/helpers/VisitedTracker.js.map +1 -0
- package/packages/ai/src/lib/dataStructure/helpers/cleanNonObjectFunctions.js +55 -1
- package/packages/ai/src/lib/dataStructure/helpers/cleanNonObjectFunctions.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.js +14 -6
- package/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/helpers/selectBestValue.js +62 -0
- package/packages/ai/src/lib/dataStructure/helpers/selectBestValue.js.map +1 -0
- package/packages/ai/src/lib/dataStructure/helpers/uniqueIdUtils.js +90 -0
- package/packages/ai/src/lib/dataStructure/helpers/uniqueIdUtils.js.map +1 -0
- package/packages/ai/src/lib/gatherRelevantDependentKeyAttributes.js +22 -0
- package/packages/ai/src/lib/gatherRelevantDependentKeyAttributes.js.map +1 -1
- package/packages/ai/src/lib/generateChangesEntityDocumentation.js +19 -1
- package/packages/ai/src/lib/generateChangesEntityDocumentation.js.map +1 -1
- package/packages/ai/src/lib/generateChangesEntityScenarioData.js +55 -156
- package/packages/ai/src/lib/generateChangesEntityScenarioData.js.map +1 -1
- package/packages/ai/src/lib/generateChangesEntityScenarios.js +79 -262
- package/packages/ai/src/lib/generateChangesEntityScenarios.js.map +1 -1
- package/packages/ai/src/lib/generateEntityDocumentation.js +15 -1
- package/packages/ai/src/lib/generateEntityDocumentation.js.map +1 -1
- package/packages/ai/src/lib/generateEntityKeyAttributes.js +32 -8
- package/packages/ai/src/lib/generateEntityKeyAttributes.js.map +1 -1
- package/packages/ai/src/lib/generateEntityScenarioData.js +52 -152
- package/packages/ai/src/lib/generateEntityScenarioData.js.map +1 -1
- package/packages/ai/src/lib/generateEntityScenarios.js +88 -258
- package/packages/ai/src/lib/generateEntityScenarios.js.map +1 -1
- package/packages/ai/src/lib/generateStatementAnalysis.js +46 -71
- package/packages/ai/src/lib/generateStatementAnalysis.js.map +1 -1
- package/packages/ai/src/lib/getConditionalUsagesFromCode.js +13 -8
- package/packages/ai/src/lib/getConditionalUsagesFromCode.js.map +1 -1
- package/packages/ai/src/lib/getLLMCallStats.js +0 -14
- package/packages/ai/src/lib/getLLMCallStats.js.map +1 -1
- package/packages/ai/src/lib/modelInfo.js +15 -0
- package/packages/ai/src/lib/modelInfo.js.map +1 -1
- package/packages/ai/src/lib/promptGenerators/gatherAttributesMap.js +36 -3
- package/packages/ai/src/lib/promptGenerators/gatherAttributesMap.js.map +1 -1
- package/packages/ai/src/lib/promptGenerators/generateChangesEntityDocumentationGenerator.js +8 -33
- package/packages/ai/src/lib/promptGenerators/generateChangesEntityDocumentationGenerator.js.map +1 -1
- package/packages/ai/src/lib/promptGenerators/generateChangesEntityScenarioDataGenerator.js +35 -41
- package/packages/ai/src/lib/promptGenerators/generateChangesEntityScenarioDataGenerator.js.map +1 -1
- package/packages/ai/src/lib/promptGenerators/generateChangesEntityScenariosGenerator.js +59 -72
- package/packages/ai/src/lib/promptGenerators/generateChangesEntityScenariosGenerator.js.map +1 -1
- package/packages/ai/src/lib/promptGenerators/generateEntityDocumentationGenerator.js +8 -27
- package/packages/ai/src/lib/promptGenerators/generateEntityDocumentationGenerator.js.map +1 -1
- package/packages/ai/src/lib/promptGenerators/generateEntityScenarioDataGenerator.js +24 -27
- package/packages/ai/src/lib/promptGenerators/generateEntityScenarioDataGenerator.js.map +1 -1
- package/packages/ai/src/lib/promptGenerators/generateEntityScenariosGenerator.js +21 -22
- package/packages/ai/src/lib/promptGenerators/generateEntityScenariosGenerator.js.map +1 -1
- package/packages/ai/src/lib/types/index.js +2 -0
- package/packages/ai/src/lib/types/index.js.map +1 -1
- package/packages/ai/src/lib/worker/SerializableDataStructure.js +7 -0
- package/packages/ai/src/lib/worker/SerializableDataStructure.js.map +1 -1
- package/packages/analyze/src/lib/FileAnalyzer.js +39 -7
- package/packages/analyze/src/lib/FileAnalyzer.js.map +1 -1
- package/packages/analyze/src/lib/asts/nodes/getNodeType.js +1 -1
- package/packages/analyze/src/lib/asts/nodes/getNodeType.js.map +1 -1
- package/packages/analyze/src/lib/asts/nodes/index.js +2 -1
- package/packages/analyze/src/lib/asts/nodes/index.js.map +1 -1
- package/packages/analyze/src/lib/asts/sourceFiles/getAllExportedNodes.js +3 -2
- package/packages/analyze/src/lib/asts/sourceFiles/getAllExportedNodes.js.map +1 -1
- package/packages/analyze/src/lib/asts/sourceFiles/getAllExports.js +4 -3
- package/packages/analyze/src/lib/asts/sourceFiles/getAllExports.js.map +1 -1
- package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js +6 -8
- package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js.map +1 -1
- package/packages/analyze/src/lib/files/analyze/analyzeEntities.js +5 -1
- package/packages/analyze/src/lib/files/analyze/analyzeEntities.js.map +1 -1
- package/packages/analyze/src/lib/files/analyze/gatherEntityMap.js +8 -2
- package/packages/analyze/src/lib/files/analyze/gatherEntityMap.js.map +1 -1
- package/packages/analyze/src/lib/files/analyze/trackEntityCircularDependencies.js +5 -8
- package/packages/analyze/src/lib/files/analyze/trackEntityCircularDependencies.js.map +1 -1
- package/packages/analyze/src/lib/files/analyzeChange.js +21 -9
- package/packages/analyze/src/lib/files/analyzeChange.js.map +1 -1
- package/packages/analyze/src/lib/files/analyzeEntity.js +10 -4
- package/packages/analyze/src/lib/files/analyzeEntity.js.map +1 -1
- package/packages/analyze/src/lib/files/analyzeInitial.js +21 -9
- package/packages/analyze/src/lib/files/analyzeInitial.js.map +1 -1
- package/packages/analyze/src/lib/files/analyzeRemixRoute.js +18 -23
- package/packages/analyze/src/lib/files/analyzeRemixRoute.js.map +1 -1
- package/packages/analyze/src/lib/files/getImportedExports.js +56 -4
- package/packages/analyze/src/lib/files/getImportedExports.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.js +24 -0
- package/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/generateDataStructure.js +6 -1
- package/packages/analyze/src/lib/files/scenarios/generateDataStructure.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/generateKeyAttributes.js +9 -1
- package/packages/analyze/src/lib/files/scenarios/generateKeyAttributes.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/generateScenarioData.js +5 -1
- package/packages/analyze/src/lib/files/scenarios/generateScenarioData.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/generateScenarios.js +9 -1
- package/packages/analyze/src/lib/files/scenarios/generateScenarios.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js +16 -7
- package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/mergeValidatedDataStructures.js +8 -2
- package/packages/analyze/src/lib/files/scenarios/mergeValidatedDataStructures.js.map +1 -1
- package/packages/generate/src/lib/componentScenarioPage/componentScenarioPageNext.js +28 -21
- package/packages/generate/src/lib/componentScenarioPage/componentScenarioPageNext.js.map +1 -1
- package/packages/generate/src/lib/componentScenarioPage/componentScenarioPageRemix.js +18 -11
- package/packages/generate/src/lib/componentScenarioPage/componentScenarioPageRemix.js.map +1 -1
- package/packages/generate/src/lib/scenarioComponent.js +5 -3
- package/packages/generate/src/lib/scenarioComponent.js.map +1 -1
- package/packages/supabase/src/lib/kysely/db.js +3 -0
- package/packages/supabase/src/lib/kysely/db.js.map +1 -1
- package/packages/supabase/src/lib/kysely/tables/debugReportsTable.js +27 -0
- package/packages/supabase/src/lib/kysely/tables/debugReportsTable.js.map +1 -0
- package/packages/supabase/src/lib/scenarioToDb.js +1 -1
- package/packages/supabase/src/lib/scenarioToDb.js.map +1 -1
- package/packages/utils/index.js +2 -0
- package/packages/utils/index.js.map +1 -1
- package/packages/utils/src/lib/Semaphore.js +40 -0
- package/packages/utils/src/lib/Semaphore.js.map +1 -0
- package/packages/utils/src/lib/applyUniversalMocks.js +39 -5
- package/packages/utils/src/lib/applyUniversalMocks.js.map +1 -1
- package/packages/utils/src/lib/frameworks/getNextRoutePath.js +2 -1
- package/packages/utils/src/lib/frameworks/getNextRoutePath.js.map +1 -1
- package/packages/utils/src/lib/frameworks/getRemixRoutePath.js +2 -1
- package/packages/utils/src/lib/frameworks/getRemixRoutePath.js.map +1 -1
- package/packages/utils/src/lib/frameworks/nextRouteFileNameToRoute.js +2 -1
- package/packages/utils/src/lib/frameworks/nextRouteFileNameToRoute.js.map +1 -1
- package/packages/utils/src/lib/frameworks/remixRouteFileNameToRoute.js +1 -0
- package/packages/utils/src/lib/frameworks/remixRouteFileNameToRoute.js.map +1 -1
- package/packages/utils/src/lib/frameworks/sanitizeNextRouteSegments.js +32 -0
- package/packages/utils/src/lib/frameworks/sanitizeNextRouteSegments.js.map +1 -0
- package/packages/utils/src/lib/lightweightEntityExtractor.js +17 -0
- package/packages/utils/src/lib/lightweightEntityExtractor.js.map +1 -1
- package/analyzer-template/packages/ai/src/lib/generateEntityDataMap.ts +0 -375
- package/codeyam-cli/src/webserver/build/client/assets/EntityTypeIcon-rqv54FUY.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/InteractivePreview-B0oiPem-.js +0 -26
- package/codeyam-cli/src/webserver/build/client/assets/LibraryFunctionPreview-DqXXjAJ7.js +0 -3
- package/codeyam-cli/src/webserver/build/client/assets/SafeScreenshot-DU_jxCPD.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/ScenarioPreview-5DY-YIxu.js +0 -6
- package/codeyam-cli/src/webserver/build/client/assets/ScenarioViewer-DmjXUj6m.js +0 -5
- package/codeyam-cli/src/webserver/build/client/assets/_index-DvSrcxsk.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/activity.(_tab)-CsaMd9mb.js +0 -10
- package/codeyam-cli/src/webserver/build/client/assets/chart-column-VXBS6qOn.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/circle-alert-n5GUC2AS.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/clock-DKqtX8js.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/components-Dj-Ggnl2.js +0 -40
- package/codeyam-cli/src/webserver/build/client/assets/dev.empty-BbR3FwNc.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.create-scenario-L7M9Vr5z.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.edit._scenarioId-C9w-q7P3.js +0 -5
- package/codeyam-cli/src/webserver/build/client/assets/entry.client-CdGoUs8A.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/file-text-B6Er7j5k.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/files-KcDVw1FY.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/git-B9uZ8eSJ.js +0 -12
- package/codeyam-cli/src/webserver/build/client/assets/globals-B0f88RTV.css +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/loader-circle-v3c6DFp4.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/manifest-fca08d7e.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/root-Cf8VBqIb.js +0 -16
- package/codeyam-cli/src/webserver/build/client/assets/search-DA14wXpu.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/settings-COJUrwGu.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/settings-NU_ZquhK.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/simulations-CNaMJ-nR.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/useToast-BRShB17p.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/zap-BvukH0eN.js +0 -1
- package/codeyam-cli/src/webserver/build/client/cy-logo-cli.svg +0 -13
- package/codeyam-cli/src/webserver/build/client/favicon.svg +0 -13
- package/codeyam-cli/src/webserver/build/server/assets/index-DHr4rT4u.js +0 -1
- package/codeyam-cli/src/webserver/build/server/assets/server-build-Bi1mj14J.js +0 -166
- package/codeyam-cli/src/webserver/public/cy-logo-cli.svg +0 -13
- package/codeyam-cli/src/webserver/public/favicon.svg +0 -13
- package/packages/ai/src/lib/generateEntityDataMap.js +0 -335
- package/packages/ai/src/lib/generateEntityDataMap.js.map +0 -1
- package/packages/ai/src/lib/promptGenerators/generateEntityDataMapGenerator.js +0 -17
- package/packages/ai/src/lib/promptGenerators/generateEntityDataMapGenerator.js.map +0 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Analysis,
|
|
3
3
|
Entity,
|
|
4
|
+
EntityType,
|
|
4
5
|
File,
|
|
5
6
|
Scenario,
|
|
6
7
|
Project,
|
|
@@ -25,6 +26,14 @@ import * as fs from 'fs';
|
|
|
25
26
|
import * as path from 'path';
|
|
26
27
|
import { LazyFileStore } from './LazyFileStore';
|
|
27
28
|
|
|
29
|
+
/**
|
|
30
|
+
* Escape special regex characters in a string so it can be used as a literal pattern.
|
|
31
|
+
* This prevents characters like . * + ? ^ $ { } ( ) | [ ] \ from being interpreted as regex metacharacters.
|
|
32
|
+
*/
|
|
33
|
+
function escapeRegExp(str: string): string {
|
|
34
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
35
|
+
}
|
|
36
|
+
|
|
28
37
|
interface WriteScenarioComponentsArgs {
|
|
29
38
|
project: Project;
|
|
30
39
|
file: File;
|
|
@@ -43,14 +52,22 @@ interface WriteScenarioComponentsArgs {
|
|
|
43
52
|
})[];
|
|
44
53
|
writtenScenarioComponents?: { [key: string]: string[] };
|
|
45
54
|
fileStore?: LazyFileStore;
|
|
55
|
+
/**
|
|
56
|
+
* When a default export needs to be accessible as a named export (e.g., when
|
|
57
|
+
* the parent imports it as `{ Name }` via an index re-export), pass the name here.
|
|
58
|
+
* A re-export statement `export { default as Name };` will be added to the output.
|
|
59
|
+
*/
|
|
60
|
+
exportAsNamed?: string;
|
|
46
61
|
}
|
|
47
62
|
|
|
48
63
|
type EnhancedImportedExport = Omit<
|
|
49
64
|
Entity['metadata']['importedExports'][0],
|
|
50
|
-
'
|
|
65
|
+
'calls' | 'entityType'
|
|
51
66
|
> & {
|
|
52
67
|
analysisId: string;
|
|
53
68
|
isNodeModule?: boolean;
|
|
69
|
+
entityType?: EntityType; // Optional because nodeModuleImports don't have it
|
|
70
|
+
calls?: readonly string[]; // Optional - used for Zod schema detection heuristic
|
|
54
71
|
};
|
|
55
72
|
|
|
56
73
|
function hasMockStructure(
|
|
@@ -73,6 +90,7 @@ function hasMockStructure(
|
|
|
73
90
|
importedExport.filePath
|
|
74
91
|
]?.[importedExport.name],
|
|
75
92
|
)?.metadata?.mergedDataStructure?.dependencySchemas,
|
|
93
|
+
importedExport.entityType,
|
|
76
94
|
);
|
|
77
95
|
}
|
|
78
96
|
|
|
@@ -83,54 +101,340 @@ function isIndexPath(filePath: string) {
|
|
|
83
101
|
}
|
|
84
102
|
|
|
85
103
|
/**
|
|
86
|
-
*
|
|
87
|
-
*
|
|
104
|
+
* Convert .d.ts type declaration content to stub implementations.
|
|
105
|
+
* .d.ts files only have type declarations which don't provide runtime exports.
|
|
106
|
+
* This function converts them to actual stub implementations.
|
|
88
107
|
*
|
|
89
|
-
*
|
|
108
|
+
* @param content - The .d.ts file content
|
|
109
|
+
* @param entityName - The name of the entity we're generating for (used to ensure it's exported)
|
|
110
|
+
* @returns The converted content with stub implementations
|
|
111
|
+
*/
|
|
112
|
+
function convertDtsToStubs(content: string, entityName: string): string {
|
|
113
|
+
let result = content;
|
|
114
|
+
|
|
115
|
+
// Handle object types FIRST (before simple types) since they span multiple lines
|
|
116
|
+
// and contain semicolons that would incorrectly terminate the simple type regex
|
|
117
|
+
|
|
118
|
+
// Convert "export declare const NAME: { ... };" (object type) to "export const NAME = {} as any;"
|
|
119
|
+
result = result.replace(
|
|
120
|
+
/export\s+declare\s+const\s+(\w+)\s*:\s*\{[^}]*\}\s*;/gs,
|
|
121
|
+
'export const $1 = {} as any;',
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
// Convert "export declare let NAME: { ... };" (object type) to "export let NAME = {} as any;"
|
|
125
|
+
result = result.replace(
|
|
126
|
+
/export\s+declare\s+let\s+(\w+)\s*:\s*\{[^}]*\}\s*;/gs,
|
|
127
|
+
'export let $1 = {} as any;',
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
// Convert "export declare var NAME: { ... };" (object type) to "export var NAME = {} as any;"
|
|
131
|
+
result = result.replace(
|
|
132
|
+
/export\s+declare\s+var\s+(\w+)\s*:\s*\{[^}]*\}\s*;/gs,
|
|
133
|
+
'export var $1 = {} as any;',
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
// Now handle simple types (non-object types)
|
|
137
|
+
|
|
138
|
+
// Convert "export declare const NAME: TYPE;" to "export const NAME = {} as any;"
|
|
139
|
+
result = result.replace(
|
|
140
|
+
/export\s+declare\s+const\s+(\w+)\s*:\s*[^;]+;/g,
|
|
141
|
+
'export const $1 = {} as any;',
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
// Convert "export declare let NAME: TYPE;" to "export let NAME = {} as any;"
|
|
145
|
+
result = result.replace(
|
|
146
|
+
/export\s+declare\s+let\s+(\w+)\s*:\s*[^;]+;/g,
|
|
147
|
+
'export let $1 = {} as any;',
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
// Convert "export declare var NAME: TYPE;" to "export var NAME = {} as any;"
|
|
151
|
+
result = result.replace(
|
|
152
|
+
/export\s+declare\s+var\s+(\w+)\s*:\s*[^;]+;/g,
|
|
153
|
+
'export var $1 = {} as any;',
|
|
154
|
+
);
|
|
155
|
+
|
|
156
|
+
// Convert "export declare function NAME(...): TYPE;" to "export function NAME() { return {} as any; }"
|
|
157
|
+
result = result.replace(
|
|
158
|
+
/export\s+declare\s+function\s+(\w+)\s*\([^)]*\)\s*:\s*[^;]+;/g,
|
|
159
|
+
'export function $1(...args: any[]) { return {} as any; }',
|
|
160
|
+
);
|
|
161
|
+
|
|
162
|
+
// Convert "export declare class NAME { ... }" to "export class NAME {}"
|
|
163
|
+
// This is tricky because class bodies can span multiple lines
|
|
164
|
+
result = result.replace(
|
|
165
|
+
/export\s+declare\s+class\s+(\w+)\s*(?:extends\s+[^{]+)?\{[^}]*\}/gs,
|
|
166
|
+
'export class $1 {}',
|
|
167
|
+
);
|
|
168
|
+
|
|
169
|
+
// Convert "declare const NAME: { ... }" (object type, non-exported) to "const NAME = {} as any;"
|
|
170
|
+
// Object types can span multiple lines and contain semicolons, so we handle them separately
|
|
171
|
+
// The 's' flag makes . match newlines, so this matches the entire object type block
|
|
172
|
+
result = result.replace(
|
|
173
|
+
/^declare\s+const\s+(\w+)\s*:\s*\{[^}]*\}\s*;/gms,
|
|
174
|
+
'const $1 = {} as any;',
|
|
175
|
+
);
|
|
176
|
+
|
|
177
|
+
// Convert "declare const NAME: TYPE;" (simple type, non-exported) to "const NAME = {} as any;"
|
|
178
|
+
// These are often used with "export { NAME }" at the end
|
|
179
|
+
// This must come AFTER the object type handler above
|
|
180
|
+
result = result.replace(
|
|
181
|
+
/^declare\s+const\s+(\w+)\s*:\s*[^;]+;/gm,
|
|
182
|
+
'const $1 = {} as any;',
|
|
183
|
+
);
|
|
184
|
+
|
|
185
|
+
// Convert "declare function NAME" (non-exported) to "function NAME() { return {} as any; }"
|
|
186
|
+
result = result.replace(
|
|
187
|
+
/^declare\s+function\s+(\w+)\s*\([^)]*\)\s*:\s*[^;]+;/gm,
|
|
188
|
+
'function $1(...args: any[]) { return {} as any; }',
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
// Convert "declare class NAME" (non-exported) to "class NAME {}"
|
|
192
|
+
result = result.replace(
|
|
193
|
+
/^declare\s+class\s+(\w+)\s*(?:extends\s+[^{]+)?\{[^}]*\}/gm,
|
|
194
|
+
'class $1 {}',
|
|
195
|
+
);
|
|
196
|
+
|
|
197
|
+
// Remove "export { }" at the end (empty export statement that marks module as having no exports)
|
|
198
|
+
result = result.replace(/export\s*\{\s*\}\s*;?\s*$/g, '');
|
|
199
|
+
|
|
200
|
+
// Keep export type and export interface statements as-is (they're valid in .ts)
|
|
201
|
+
// No transformation needed for these
|
|
202
|
+
|
|
203
|
+
console.log(
|
|
204
|
+
`CodeYam: Converted .d.ts content for entity "${entityName}". Result length: ${result.length}`,
|
|
205
|
+
);
|
|
206
|
+
|
|
207
|
+
return result;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Rewrite relative asset paths to correct locations when a file is moved.
|
|
212
|
+
*
|
|
213
|
+
* This function generically handles ANY string literal containing a relative path
|
|
214
|
+
* to an asset file, not just import statements. This catches patterns like:
|
|
90
215
|
* - import "./globals.css"
|
|
91
216
|
* - import styles from "./file.module.css"
|
|
92
|
-
* -
|
|
217
|
+
* - localFont({ src: "../fonts/font.woff2" })
|
|
218
|
+
* - Image src="../images/logo.png"
|
|
219
|
+
* - Any other string literal with a relative asset path
|
|
93
220
|
*/
|
|
94
221
|
function rewriteAssetImports(
|
|
95
222
|
fileContent: string,
|
|
96
223
|
originalFilePath: string,
|
|
97
224
|
newFilePath: string,
|
|
98
225
|
): string {
|
|
99
|
-
//
|
|
226
|
+
// Asset file extensions that should have their paths rewritten
|
|
100
227
|
const assetExtensions =
|
|
101
228
|
'css|scss|sass|less|styl|png|jpg|jpeg|gif|svg|webp|ico|woff|woff2|ttf|eot|otf|mp4|webm|json';
|
|
102
|
-
|
|
103
|
-
|
|
229
|
+
|
|
230
|
+
// Match ANY string literal containing a relative path to an asset file
|
|
231
|
+
// This captures both single and double quoted strings that start with ./ or ../
|
|
232
|
+
const relativeAssetPathRegex = new RegExp(
|
|
233
|
+
`(['"])(\\.{1,2}/[^'"]*\\.(?:${assetExtensions}))\\1`,
|
|
104
234
|
'g',
|
|
105
235
|
);
|
|
106
236
|
|
|
107
237
|
// Get the directory part of the original file path (relative to project root)
|
|
108
238
|
const originalDirParts = originalFilePath.split('/').slice(0, -1);
|
|
109
239
|
|
|
110
|
-
return fileContent.replace(
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
240
|
+
return fileContent.replace(
|
|
241
|
+
relativeAssetPathRegex,
|
|
242
|
+
(match, quote, assetPath) => {
|
|
243
|
+
// Resolve the asset path relative to the original file's directory
|
|
244
|
+
// We need to manually resolve the relative path without using path.resolve
|
|
245
|
+
// which would resolve against the actual filesystem
|
|
246
|
+
const pathParts = assetPath.split('/');
|
|
247
|
+
const resolvedParts = [...originalDirParts];
|
|
248
|
+
|
|
249
|
+
for (const part of pathParts) {
|
|
250
|
+
if (part === '..') {
|
|
251
|
+
resolvedParts.pop();
|
|
252
|
+
} else if (part !== '.') {
|
|
253
|
+
resolvedParts.push(part);
|
|
254
|
+
}
|
|
122
255
|
}
|
|
123
|
-
}
|
|
124
256
|
|
|
125
|
-
|
|
126
|
-
|
|
257
|
+
// Build the project-relative path to the asset
|
|
258
|
+
const absoluteAssetPath = resolvedParts.join('/');
|
|
127
259
|
|
|
128
|
-
|
|
129
|
-
|
|
260
|
+
// Calculate the new relative path from new file location
|
|
261
|
+
const newRelativePath = getRelativePath(newFilePath, absoluteAssetPath);
|
|
130
262
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
263
|
+
// Replace the path in the original match, preserving the quote style
|
|
264
|
+
return `${quote}${newRelativePath}${quote}`;
|
|
265
|
+
},
|
|
266
|
+
);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Rewrite relative TypeScript/JavaScript module imports when a file is moved.
|
|
271
|
+
*
|
|
272
|
+
* When a file is moved from one location to another (e.g., from [environmentId]/
|
|
273
|
+
* to _environmentId_/), relative imports like "./lib/organization" need to be
|
|
274
|
+
* rewritten to point to the correct location from the new path.
|
|
275
|
+
*
|
|
276
|
+
* This is similar to rewriteAssetImports but handles TypeScript/JavaScript modules
|
|
277
|
+
* instead of asset files (CSS, images, etc.).
|
|
278
|
+
*/
|
|
279
|
+
function rewriteRelativeModuleImports(
|
|
280
|
+
fileContent: string,
|
|
281
|
+
originalFilePath: string,
|
|
282
|
+
newFilePath: string,
|
|
283
|
+
): string {
|
|
284
|
+
// Module file extensions that should have their relative paths rewritten
|
|
285
|
+
const moduleExtensions = 'ts|tsx|js|jsx|mjs|cjs';
|
|
286
|
+
|
|
287
|
+
// Match import statements with relative paths (starting with ./ or ../)
|
|
288
|
+
// This matches:
|
|
289
|
+
// - import { foo } from "./path"
|
|
290
|
+
// - import foo from "../path"
|
|
291
|
+
// - import * as foo from "./path"
|
|
292
|
+
// - import "./path" (side-effect imports)
|
|
293
|
+
// The path may or may not have a file extension
|
|
294
|
+
const relativeImportRegex = new RegExp(
|
|
295
|
+
`(from\\s+)(['"])(\\.\\.?\\/[^'"]+?)(?:\\.(?:${moduleExtensions}))?\\2`,
|
|
296
|
+
'g',
|
|
297
|
+
);
|
|
298
|
+
|
|
299
|
+
// Get the directory part of the original file path (relative to project root)
|
|
300
|
+
const originalDirParts = originalFilePath.split('/').slice(0, -1);
|
|
301
|
+
|
|
302
|
+
return fileContent.replace(
|
|
303
|
+
relativeImportRegex,
|
|
304
|
+
(match, fromKeyword, quote, importPath) => {
|
|
305
|
+
// Skip imports that already point to generated CodeYam files:
|
|
306
|
+
// 1. Scenario component files with SHA hashes (64 hex chars) and scenario name suffixes
|
|
307
|
+
// e.g., "abc123def_EnvironmentLayout_Empty_Survey_No_Responses"
|
|
308
|
+
// 2. Mock data files in __codeyamMocks__ directory
|
|
309
|
+
// e.g., "../__codeyamMocks__/MockData_Empty_Survey_No_Responses"
|
|
310
|
+
const scenarioFilePattern = /[a-f0-9]{64}_\w+_[A-Z][a-zA-Z_]+$/;
|
|
311
|
+
const mockDataPattern = /__codeyamMocks__\//;
|
|
312
|
+
if (
|
|
313
|
+
scenarioFilePattern.test(importPath) ||
|
|
314
|
+
mockDataPattern.test(importPath)
|
|
315
|
+
) {
|
|
316
|
+
// This import already points to a generated file, don't rewrite it
|
|
317
|
+
return match;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// Resolve the import path relative to the original file's directory
|
|
321
|
+
const pathParts = importPath.split('/');
|
|
322
|
+
const resolvedParts = [...originalDirParts];
|
|
323
|
+
|
|
324
|
+
for (const part of pathParts) {
|
|
325
|
+
if (part === '..') {
|
|
326
|
+
resolvedParts.pop();
|
|
327
|
+
} else if (part !== '.') {
|
|
328
|
+
resolvedParts.push(part);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// Build the project-relative path to the module
|
|
333
|
+
const absoluteModulePath = resolvedParts.join('/');
|
|
334
|
+
|
|
335
|
+
// Calculate the new relative path from new file location
|
|
336
|
+
const newRelativePath = getRelativePath(newFilePath, absoluteModulePath);
|
|
337
|
+
|
|
338
|
+
// Replace the path in the original match, preserving the quote style
|
|
339
|
+
return `${fromKeyword}${quote}${newRelativePath}${quote}`;
|
|
340
|
+
},
|
|
341
|
+
);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* Strip <html> and <body> tags from root layout files for Next.js App Router.
|
|
346
|
+
*
|
|
347
|
+
* When a root layout (app/layout.tsx) is generated as a scenario component and placed
|
|
348
|
+
* under the /static/ route, it becomes nested under the real app root layout. Having
|
|
349
|
+
* two layouts with <html> and <body> tags causes hydration errors:
|
|
350
|
+
*
|
|
351
|
+
* "In HTML, <html> cannot be a child of <body>"
|
|
352
|
+
* "You are mounting a new html component when a previous one has not first unmounted"
|
|
353
|
+
*
|
|
354
|
+
* This function removes the <html> and <body> wrapper tags while preserving the inner
|
|
355
|
+
* content, allowing the scenario layout to work correctly when nested.
|
|
356
|
+
*
|
|
357
|
+
* Before: <html lang="en"><body className={...}><main>{children}</main></body></html>
|
|
358
|
+
* After: <div className={...}><main>{children}</main></div>
|
|
359
|
+
*/
|
|
360
|
+
function stripHtmlBodyTags(
|
|
361
|
+
fileContent: string,
|
|
362
|
+
filePath: string,
|
|
363
|
+
framework: ProjectFramework,
|
|
364
|
+
): string {
|
|
365
|
+
// Only apply to Next.js App Router root layouts
|
|
366
|
+
if (framework !== ProjectFramework.Next) {
|
|
367
|
+
return fileContent;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// Check if this is a root layout file (typically app/layout.tsx or apps/*/app/layout.tsx)
|
|
371
|
+
// Root layouts are at the app directory level, not in subdirectories like (app)/ or routes/
|
|
372
|
+
const pathParts = filePath.split('/');
|
|
373
|
+
const fileName = pathParts[pathParts.length - 1];
|
|
374
|
+
|
|
375
|
+
// Must be a layout file
|
|
376
|
+
if (!fileName?.startsWith('layout.')) {
|
|
377
|
+
return fileContent;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// Check if it's at the app root level (parent directory is 'app')
|
|
381
|
+
const parentDir = pathParts[pathParts.length - 2];
|
|
382
|
+
if (parentDir !== 'app') {
|
|
383
|
+
return fileContent;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
// Check if this file actually contains <html> and <body> tags
|
|
387
|
+
if (!/<html[^>]*>/.test(fileContent) || !/<body[^>]*>/.test(fileContent)) {
|
|
388
|
+
return fileContent;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
console.log(
|
|
392
|
+
`CodeYam: Stripping <html> and <body> tags from root layout: ${filePath}`,
|
|
393
|
+
);
|
|
394
|
+
|
|
395
|
+
// Extract the body className/attributes if any, to preserve styling
|
|
396
|
+
const bodyMatch = fileContent.match(/<body([^>]*)>/);
|
|
397
|
+
const bodyAttributes = bodyMatch?.[1]?.trim() || '';
|
|
398
|
+
|
|
399
|
+
// Replace the JSX structure:
|
|
400
|
+
// <html ...><body ...>CONTENT</body></html>
|
|
401
|
+
// With: <div ...>CONTENT</div>
|
|
402
|
+
//
|
|
403
|
+
// This regex handles:
|
|
404
|
+
// 1. Opening <html> tag with any attributes
|
|
405
|
+
// 2. Opening <body> tag with any attributes (captured for the wrapper div)
|
|
406
|
+
// 3. Content between body tags (captured)
|
|
407
|
+
// 4. Closing </body> and </html> tags
|
|
408
|
+
const htmlBodyRegex =
|
|
409
|
+
/(<html[^>]*>\s*<body)([^>]*)(>)([\s\S]*?)(<\/body>\s*<\/html>)/g;
|
|
410
|
+
|
|
411
|
+
let result = fileContent.replace(
|
|
412
|
+
htmlBodyRegex,
|
|
413
|
+
(match, _htmlBody, bodyAttrs, closeBracket, content, _closing) => {
|
|
414
|
+
// Create a wrapper div with the body's attributes
|
|
415
|
+
const attrs = bodyAttrs?.trim() || '';
|
|
416
|
+
if (attrs) {
|
|
417
|
+
return `(<div${bodyAttrs}${closeBracket}${content}</div>)`;
|
|
418
|
+
} else {
|
|
419
|
+
return `(<>${content}</>)`;
|
|
420
|
+
}
|
|
421
|
+
},
|
|
422
|
+
);
|
|
423
|
+
|
|
424
|
+
// If the regex didn't match (perhaps due to different formatting),
|
|
425
|
+
// try a more lenient approach - just remove the tags
|
|
426
|
+
if (result === fileContent) {
|
|
427
|
+
// Remove <html ...> opening tag
|
|
428
|
+
result = result.replace(/<html[^>]*>\s*/g, '');
|
|
429
|
+
// Remove </html> closing tag
|
|
430
|
+
result = result.replace(/\s*<\/html>/g, '');
|
|
431
|
+
// Replace <body ...> with <div ...> to preserve attributes
|
|
432
|
+
result = result.replace(/<body([^>]*)>/g, '<div$1>');
|
|
433
|
+
// Replace </body> with </div>
|
|
434
|
+
result = result.replace(/<\/body>/g, '</div>');
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
return result;
|
|
134
438
|
}
|
|
135
439
|
|
|
136
440
|
function addMockToContent(
|
|
@@ -157,7 +461,11 @@ function addMockToContent(
|
|
|
157
461
|
rootAnalysis.metadata?.mergedDataStructure?.dependencySchemas;
|
|
158
462
|
}
|
|
159
463
|
|
|
160
|
-
const mockCode = constructMockCode(
|
|
464
|
+
const mockCode = constructMockCode(
|
|
465
|
+
importedExport.name,
|
|
466
|
+
dependencySchemas,
|
|
467
|
+
importedExport.entityType,
|
|
468
|
+
);
|
|
161
469
|
|
|
162
470
|
if (!mockCode) {
|
|
163
471
|
console.log(
|
|
@@ -204,8 +512,13 @@ function addMockToContent(
|
|
|
204
512
|
);
|
|
205
513
|
fileContent = fileContent.replace(entireImportRegExp, '');
|
|
206
514
|
} else {
|
|
515
|
+
// Escape regex special characters in importPath (e.g., brackets in [environmentId])
|
|
516
|
+
const escapedImportPath = importPath.replace(
|
|
517
|
+
/[.*+?^${}()|[\]\\]/g,
|
|
518
|
+
'\\$&',
|
|
519
|
+
);
|
|
207
520
|
const importRegExp = new RegExp(
|
|
208
|
-
`(import(?:(?!${firstPart}|from|import)[\\s\\S])*?)${firstPart}(?:,\\s*)?((?:(?!import)[\\s\\S])*?from\\s+['"]${
|
|
521
|
+
`(import(?:(?!${firstPart}|from|import)[\\s\\S])*?)${firstPart}(?:,\\s*)?((?:(?!import)[\\s\\S])*?from\\s+['"]${escapedImportPath}['"])`,
|
|
209
522
|
'm',
|
|
210
523
|
);
|
|
211
524
|
|
|
@@ -225,6 +538,38 @@ function addMockToContent(
|
|
|
225
538
|
'',
|
|
226
539
|
);
|
|
227
540
|
}
|
|
541
|
+
} else {
|
|
542
|
+
// Fallback: When importPath is undefined (e.g., path alias not in mapping),
|
|
543
|
+
// we still need to remove the import to avoid "name defined multiple times" errors.
|
|
544
|
+
// Search for the entity name in any import statement and remove it.
|
|
545
|
+
const importedExportNameParts = splitOutsideParenthesesAndArrays(
|
|
546
|
+
importedExport.name,
|
|
547
|
+
);
|
|
548
|
+
const firstPart = importedExportNameParts[0];
|
|
549
|
+
|
|
550
|
+
// Match the entity name in any named import and remove just that name
|
|
551
|
+
// This handles imports like: import { useEnvironment, otherThing } from "any/path"
|
|
552
|
+
// Removes useEnvironment but keeps otherThing
|
|
553
|
+
const namedImportRegExp = new RegExp(
|
|
554
|
+
`(import\\s*\\{[^}]*?)\\b${escapeRegExp(firstPart)}\\b(?:,\\s*|\\s*,)?((?:[^}]*\\}\\s*from\\s*['"][^'"]*['"];?))`,
|
|
555
|
+
'm',
|
|
556
|
+
);
|
|
557
|
+
|
|
558
|
+
if (importedExportNameParts.length > 1) {
|
|
559
|
+
// Rename the import instead of removing (for destructured access patterns)
|
|
560
|
+
fileContent = fileContent.replace(
|
|
561
|
+
namedImportRegExp,
|
|
562
|
+
`$1${firstPart}__cyOriginal$2`,
|
|
563
|
+
);
|
|
564
|
+
} else {
|
|
565
|
+
fileContent = fileContent.replace(namedImportRegExp, '$1$2');
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
// Clean up empty imports that might result from removing the only import
|
|
569
|
+
fileContent = fileContent.replace(
|
|
570
|
+
/import\s*\{\s*\}\s*from\s+['"][^'"]*['"];?\s*\n?/g,
|
|
571
|
+
'',
|
|
572
|
+
);
|
|
228
573
|
}
|
|
229
574
|
|
|
230
575
|
if (fileContent.indexOf('import { scenarios } from') === -1) {
|
|
@@ -409,6 +754,7 @@ export default async function writeScenarioComponents({
|
|
|
409
754
|
namespaceMocks,
|
|
410
755
|
writtenScenarioComponents = {},
|
|
411
756
|
fileStore,
|
|
757
|
+
exportAsNamed,
|
|
412
758
|
}: WriteScenarioComponentsArgs): Promise<{
|
|
413
759
|
scenarioComponentPaths: string[];
|
|
414
760
|
writtenScenarioComponents: { [key: string]: string[] };
|
|
@@ -529,6 +875,29 @@ export default async function writeScenarioComponents({
|
|
|
529
875
|
);
|
|
530
876
|
|
|
531
877
|
let fileContent = file.content;
|
|
878
|
+
|
|
879
|
+
// Handle .d.ts files: convert type declarations to stub implementations
|
|
880
|
+
// .d.ts files only have type declarations (e.g., "export declare const logger")
|
|
881
|
+
// which don't provide runtime exports. We need to generate actual stub implementations.
|
|
882
|
+
if (file.path.endsWith('.d.ts')) {
|
|
883
|
+
console.log(
|
|
884
|
+
`CodeYam: Converting .d.ts file to stub implementations: ${file.path}`,
|
|
885
|
+
);
|
|
886
|
+
fileContent = convertDtsToStubs(fileContent, entity.name);
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
// Extract "use client" or "use server" directive FIRST, before any modifications
|
|
890
|
+
// This ensures the directive isn't buried by prepended imports
|
|
891
|
+
const directiveMatch = fileContent.match(
|
|
892
|
+
/^(\s*["']use (client|server)["'];?\s*\n?)/,
|
|
893
|
+
);
|
|
894
|
+
let extractedDirective: string | null = null;
|
|
895
|
+
if (directiveMatch) {
|
|
896
|
+
extractedDirective = directiveMatch[1].trim();
|
|
897
|
+
// Remove the directive from fileContent - we'll add it back at the very end
|
|
898
|
+
fileContent = fileContent.slice(directiveMatch[0].length);
|
|
899
|
+
}
|
|
900
|
+
|
|
532
901
|
const fileAnalyzer = projectAnalyzer.getFileAnalyzer(file);
|
|
533
902
|
const importMapping = fileAnalyzer.getRelativeImportMappings();
|
|
534
903
|
|
|
@@ -643,10 +1012,12 @@ export default async function writeScenarioComponents({
|
|
|
643
1012
|
(importedExportEntity as Entity).localFilePath = importedExport.filePath;
|
|
644
1013
|
|
|
645
1014
|
if (!importedExport.isMocked) {
|
|
1015
|
+
// Use resolvedFilePath (actual entity location) for scenario component writing.
|
|
1016
|
+
// This is critical for re-exports: when importing from index.tsx which re-exports
|
|
1017
|
+
// from a nested file, we need to write scenario components for the actual file
|
|
1018
|
+
// where the entity code lives, not the re-export file.
|
|
646
1019
|
const importedExportFilePath =
|
|
647
|
-
|
|
648
|
-
? (importedExport.resolvedFilePath ?? importedExport.filePath)
|
|
649
|
-
: importedExport.filePath;
|
|
1020
|
+
importedExport.resolvedFilePath ?? importedExport.filePath;
|
|
650
1021
|
|
|
651
1022
|
if (importedExportFilePath !== file.path) {
|
|
652
1023
|
if (
|
|
@@ -668,17 +1039,41 @@ export default async function writeScenarioComponents({
|
|
|
668
1039
|
? fileStore.getByPath(importedExportFilePath)
|
|
669
1040
|
: project.files.find((f) => f.path === importedExportFilePath);
|
|
670
1041
|
|
|
1042
|
+
// Fallback: if file at resolvedFilePath doesn't exist, try filePath
|
|
1043
|
+
// This handles cases where the actual entity file isn't in project.files
|
|
1044
|
+
// (e.g., type re-exports where only the index file is tracked)
|
|
1045
|
+
if (
|
|
1046
|
+
!fileNotMocked &&
|
|
1047
|
+
importedExport.resolvedFilePath &&
|
|
1048
|
+
importedExport.filePath !== importedExport.resolvedFilePath
|
|
1049
|
+
) {
|
|
1050
|
+
const fallbackPath = importedExport.filePath;
|
|
1051
|
+
fileNotMocked = fileStore
|
|
1052
|
+
? fileStore.getByPath(fallbackPath)
|
|
1053
|
+
: project.files.find((f) => f.path === fallbackPath);
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
// Skip if file still not found - can't write scenario component without the file
|
|
1057
|
+
if (!fileNotMocked) {
|
|
1058
|
+
continue;
|
|
1059
|
+
}
|
|
1060
|
+
|
|
671
1061
|
// Ensure content is loaded for the file
|
|
672
1062
|
if (
|
|
673
1063
|
fileNotMocked &&
|
|
674
1064
|
fileStore &&
|
|
675
|
-
!fileStore.isContentLoaded(
|
|
1065
|
+
!fileStore.isContentLoaded(fileNotMocked.path)
|
|
676
1066
|
) {
|
|
677
|
-
fileNotMocked = await fileStore.ensureContent(
|
|
678
|
-
importedExportFilePath,
|
|
679
|
-
);
|
|
1067
|
+
fileNotMocked = await fileStore.ensureContent(fileNotMocked.path);
|
|
680
1068
|
}
|
|
681
1069
|
|
|
1070
|
+
// When a default export is imported as named (via index re-export), we need
|
|
1071
|
+
// to add a named re-export to the scenario component so the import works.
|
|
1072
|
+
// e.g., if file has `export default X` but parent does `import { X } from '...'`
|
|
1073
|
+
const needsNamedReExport =
|
|
1074
|
+
importedExport.resolvedIsDefault === true &&
|
|
1075
|
+
importedExport.isDefault === false;
|
|
1076
|
+
|
|
682
1077
|
const {
|
|
683
1078
|
scenarioComponentPaths: newScenarioComponentPaths,
|
|
684
1079
|
writtenScenarioComponents: updatedWrittenScenarioComponents,
|
|
@@ -696,6 +1091,8 @@ export default async function writeScenarioComponents({
|
|
|
696
1091
|
namespaceMocks,
|
|
697
1092
|
writtenScenarioComponents,
|
|
698
1093
|
fileStore,
|
|
1094
|
+
// Pass the import name so we can add `export { default as Name };`
|
|
1095
|
+
exportAsNamed: needsNamedReExport ? importedExport.name : undefined,
|
|
699
1096
|
});
|
|
700
1097
|
writtenScenarioComponents = updatedWrittenScenarioComponents;
|
|
701
1098
|
scenarioComponentPaths.push(...newScenarioComponentPaths);
|
|
@@ -706,21 +1103,67 @@ export default async function writeScenarioComponents({
|
|
|
706
1103
|
importedExport.name !== entity.name
|
|
707
1104
|
) {
|
|
708
1105
|
// For same-file dependencies:
|
|
709
|
-
// - Strip if
|
|
710
|
-
// - Strip if
|
|
711
|
-
// -
|
|
712
|
-
const
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
1106
|
+
// - Strip and replace if we have a mock structure we can generate
|
|
1107
|
+
// - Strip and stub if isMocked is true AND it's a callable entity (visual, library, functionCall)
|
|
1108
|
+
// - Preserve as-is for data entities (like Zod schemas) that need their methods
|
|
1109
|
+
const hasMock = hasMockStructure(importedExport, fileAnalyses);
|
|
1110
|
+
const entityType = importedExport.entityType;
|
|
1111
|
+
// Data and type entities should be preserved - they're not callable and may have methods
|
|
1112
|
+
// that stubbing would break (e.g., Zod schemas with .superRefine())
|
|
1113
|
+
const isDataEntity = entityType === 'data' || entityType === 'type';
|
|
1114
|
+
|
|
1115
|
+
// Heuristic: Zod schemas are often misclassified as 'library' but should be preserved
|
|
1116
|
+
// Detect by: name starts with Z + uppercase letter, AND has Zod method calls
|
|
1117
|
+
const looksLikeZodSchema =
|
|
1118
|
+
entityType === 'library' &&
|
|
1119
|
+
/^Z[A-Z]/.test(importedExport.name) &&
|
|
1120
|
+
importedExport.calls?.some((call: string) =>
|
|
1121
|
+
/\.(superRefine|refine|transform|default|optional|nullable|array|object|string|number|boolean|parse|safeParse)\s*\(/.test(
|
|
1122
|
+
call,
|
|
1123
|
+
),
|
|
1124
|
+
);
|
|
1125
|
+
|
|
1126
|
+
if (looksLikeZodSchema) {
|
|
1127
|
+
console.log(
|
|
1128
|
+
`CodeYam: Detected Zod schema "${importedExport.name}" (misclassified as library) - will preserve`,
|
|
1129
|
+
);
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1132
|
+
// Callable entities can be safely stubbed (but not Zod schemas)
|
|
1133
|
+
const isCallable =
|
|
1134
|
+
!isDataEntity && !looksLikeZodSchema && entityType !== undefined;
|
|
1135
|
+
|
|
1136
|
+
// Determine what action to take
|
|
1137
|
+
const shouldStripAndReplace = hasMock;
|
|
1138
|
+
const shouldStripAndStub =
|
|
1139
|
+
!hasMock && importedExport.isMocked && isCallable;
|
|
1140
|
+
const shouldPreserve = !hasMock && importedExport.isMocked && !isCallable;
|
|
1141
|
+
|
|
1142
|
+
// Log warning if entityType is undefined for a mocked same-file dependency
|
|
1143
|
+
// This could indicate an analysis issue where entityType wasn't properly set
|
|
1144
|
+
if (importedExport.isMocked && entityType === undefined) {
|
|
1145
|
+
console.warn(
|
|
1146
|
+
`CodeYam: WARNING - Same-file dependency "${importedExport.name}" is isMocked but has no entityType. ` +
|
|
1147
|
+
`Treating as non-callable (will preserve). File: ${file.path}`,
|
|
1148
|
+
);
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
if (shouldPreserve) {
|
|
1152
|
+
// For data entities (like Zod schemas), don't strip or stub - preserve the original
|
|
1153
|
+
// This ensures schema methods like .superRefine() continue to work
|
|
1154
|
+
console.log(
|
|
1155
|
+
`CodeYam: Preserving ${importedExport.name} (entityType: ${entityType}) - not stripping data entities`,
|
|
1156
|
+
);
|
|
1157
|
+
// Don't modify fileContent - keep the original code
|
|
1158
|
+
} else if (shouldStripAndReplace || shouldStripAndStub) {
|
|
1159
|
+
// Strip the original code
|
|
717
1160
|
const entityCode = fileAnalyzer.getEntityCode(importedExport.name);
|
|
718
1161
|
if (entityCode) {
|
|
719
1162
|
fileContent = fileContent.replace(entityCode, '');
|
|
720
1163
|
}
|
|
721
1164
|
|
|
722
|
-
|
|
723
|
-
|
|
1165
|
+
if (shouldStripAndReplace) {
|
|
1166
|
+
// Add mock from mock structure
|
|
724
1167
|
fileContent = addMockToContent(
|
|
725
1168
|
fileContent,
|
|
726
1169
|
importedExport,
|
|
@@ -729,18 +1172,40 @@ export default async function writeScenarioComponents({
|
|
|
729
1172
|
relativeMocksDir,
|
|
730
1173
|
scenario.name,
|
|
731
1174
|
);
|
|
1175
|
+
} else if (shouldStripAndStub) {
|
|
1176
|
+
// Generate a simple stub mock that returns scenario data.
|
|
1177
|
+
// This prevents ReferenceError at runtime when the stripped
|
|
1178
|
+
// function is called (e.g., local helper functions like getInitialProps).
|
|
1179
|
+
const functionName = importedExport.name;
|
|
1180
|
+
console.log(
|
|
1181
|
+
`CodeYam: Generating stub mock for ${functionName} (entityType: ${entityType}) in ${file.path}`,
|
|
1182
|
+
);
|
|
1183
|
+
|
|
1184
|
+
// Add scenarios import if not present
|
|
1185
|
+
if (fileContent.indexOf('import { scenarios } from') === -1) {
|
|
1186
|
+
const mockDataPath = `${relativeMocksDir}/MockData_${safeFileName(scenario.name)}`;
|
|
1187
|
+
const importStatement = `import { scenarios } from "${mockDataPath}";`;
|
|
1188
|
+
fileContent = `${fileContent}\n\n\n${importStatement}`;
|
|
1189
|
+
}
|
|
1190
|
+
|
|
1191
|
+
// Generate a simple stub that returns the scenario data for this function
|
|
1192
|
+
const stubMock = `\n\n// Stub mock for local function without mock structure\nfunction ${functionName}(...args) {\n return scenarios().data()?.["${functionName}()"];\n}`;
|
|
1193
|
+
fileContent += stubMock;
|
|
732
1194
|
}
|
|
733
1195
|
}
|
|
734
1196
|
}
|
|
735
1197
|
|
|
736
1198
|
// Try to find the import mapping using different key formats
|
|
737
1199
|
// The import mapping may use either absolute or relative paths as keys
|
|
738
|
-
//
|
|
739
|
-
//
|
|
740
|
-
// resolvedFilePath="packages/types/src/types/Commit.ts"
|
|
741
|
-
// We need to generate files at the import location (index.ts), not the entity location
|
|
1200
|
+
// Use filePath (import source) for looking up the import mapping
|
|
1201
|
+
// because that's how imports are written in source code
|
|
742
1202
|
const mockFilePathRelative = importedExport.filePath;
|
|
743
1203
|
|
|
1204
|
+
// For scenario component paths, prefer resolvedFilePath (where entity actually lives)
|
|
1205
|
+
// because that's where scenario component files are written
|
|
1206
|
+
const scenarioFilePathRelative =
|
|
1207
|
+
importedExport.resolvedFilePath ?? importedExport.filePath;
|
|
1208
|
+
|
|
744
1209
|
// Try looking up with different key formats (absolute, relative, resolved absolute)
|
|
745
1210
|
// Filter out undefined keys to avoid misleading undefined lookups
|
|
746
1211
|
const lookupKeys = [
|
|
@@ -794,10 +1259,28 @@ export default async function writeScenarioComponents({
|
|
|
794
1259
|
} else {
|
|
795
1260
|
// For non-mocked imports, rewrite the import path to point to the generated scenario file
|
|
796
1261
|
// Use fileStore for O(1) lookup when available
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
1262
|
+
// First try resolvedFilePath (where entity lives), fallback to filePath (import source)
|
|
1263
|
+
let fileNotMocked = fileStore
|
|
1264
|
+
? fileStore.getByPath(scenarioFilePathRelative)
|
|
1265
|
+
: project.files.find((f) => f.path === scenarioFilePathRelative);
|
|
1266
|
+
|
|
1267
|
+
// Track which path we're actually using for the scenario component
|
|
1268
|
+
let actualScenarioFilePathRelative = scenarioFilePathRelative;
|
|
1269
|
+
if (
|
|
1270
|
+
!fileNotMocked &&
|
|
1271
|
+
importedExport.resolvedFilePath &&
|
|
1272
|
+
importedExport.filePath !== importedExport.resolvedFilePath
|
|
1273
|
+
) {
|
|
1274
|
+
// Fallback to filePath if file at resolvedFilePath doesn't exist
|
|
1275
|
+
actualScenarioFilePathRelative = importedExport.filePath;
|
|
1276
|
+
fileNotMocked = fileStore
|
|
1277
|
+
? fileStore.getByPath(actualScenarioFilePathRelative)
|
|
1278
|
+
: project.files.find(
|
|
1279
|
+
(f) => f.path === actualScenarioFilePathRelative,
|
|
1280
|
+
);
|
|
1281
|
+
}
|
|
1282
|
+
|
|
1283
|
+
const fileName = actualScenarioFilePathRelative.split('/').pop();
|
|
801
1284
|
const fileNotMockedIsIndex = isIndexPath(fileNotMocked?.path);
|
|
802
1285
|
const mockFilePath = isFrameworkRoute(
|
|
803
1286
|
fileNotMocked,
|
|
@@ -810,7 +1293,7 @@ export default async function writeScenarioComponents({
|
|
|
810
1293
|
rootFile,
|
|
811
1294
|
entity: importedExportEntity,
|
|
812
1295
|
rootAnalysis,
|
|
813
|
-
scenarioComponentPath:
|
|
1296
|
+
scenarioComponentPath: actualScenarioFilePathRelative,
|
|
814
1297
|
project,
|
|
815
1298
|
framework,
|
|
816
1299
|
scenario,
|
|
@@ -818,7 +1301,7 @@ export default async function writeScenarioComponents({
|
|
|
818
1301
|
.split('.')
|
|
819
1302
|
.slice(0, -1)
|
|
820
1303
|
.join('.')
|
|
821
|
-
:
|
|
1304
|
+
: actualScenarioFilePathRelative.replace(
|
|
822
1305
|
`${fileName}`,
|
|
823
1306
|
`${importedExportEntity.sha}_${fileNotMockedIsIndex ? 'index_' : ''}${safeFileName(importedExportEntity.name)}_${safeFileName(scenario.name)}`,
|
|
824
1307
|
);
|
|
@@ -829,11 +1312,45 @@ export default async function writeScenarioComponents({
|
|
|
829
1312
|
// Otherwise, skip rewriting (we can't find the import statement without knowing what to search for)
|
|
830
1313
|
if (mockImportMapping) {
|
|
831
1314
|
const importRegExp = new RegExp(
|
|
832
|
-
`${mockImportMapping
|
|
1315
|
+
`${escapeRegExp(mockImportMapping)}(['"])`,
|
|
833
1316
|
'g',
|
|
834
1317
|
);
|
|
835
1318
|
|
|
836
|
-
|
|
1319
|
+
// Check if the original import path still exists in the file
|
|
1320
|
+
// If it was already rewritten by another entity from the same module,
|
|
1321
|
+
// we need to add a separate import statement for this entity
|
|
1322
|
+
if (fileContent.match(importRegExp)) {
|
|
1323
|
+
fileContent = fileContent.replace(importRegExp, `${path}$1`);
|
|
1324
|
+
} else {
|
|
1325
|
+
// The import path was already rewritten - add a new import for this entity
|
|
1326
|
+
// This handles cases where multiple entities are imported from the same index file
|
|
1327
|
+
// (e.g., import { A, B, C } from '@pkg') and each has its own scenario file
|
|
1328
|
+
const entityImportName = importedExport.name;
|
|
1329
|
+
const newImport = `import { ${entityImportName} } from '${path}';`;
|
|
1330
|
+
|
|
1331
|
+
// First, try to remove this entity from the already-rewritten grouped import
|
|
1332
|
+
// This prevents duplicate/conflicting imports
|
|
1333
|
+
// Match patterns like "EntityName," or ", EntityName" or "EntityName" (if only one)
|
|
1334
|
+
// Note: entityImportName needs escaping since JS identifiers can contain $ (a regex metacharacter)
|
|
1335
|
+
const escapedEntityName = escapeRegExp(entityImportName);
|
|
1336
|
+
const removeFromGroupedImportPatterns = [
|
|
1337
|
+
new RegExp(`\\b${escapedEntityName}\\s*,\\s*`, 'g'), // "EntityName, "
|
|
1338
|
+
new RegExp(`\\s*,\\s*${escapedEntityName}\\b`, 'g'), // ", EntityName"
|
|
1339
|
+
];
|
|
1340
|
+
for (const pattern of removeFromGroupedImportPatterns) {
|
|
1341
|
+
fileContent = fileContent.replace(pattern, '');
|
|
1342
|
+
}
|
|
1343
|
+
|
|
1344
|
+
// Add the new import at the beginning of fileContent
|
|
1345
|
+
// Note: The header comment (// Scenario:) doesn't exist yet - it's prepended at writeFile time
|
|
1346
|
+
// So prepending here puts the import right after the header in the final output
|
|
1347
|
+
//
|
|
1348
|
+
// IMPORTANT: We cannot use indexOf('// Scenario:') + '\n\n' here because:
|
|
1349
|
+
// 1. The header doesn't exist during processing
|
|
1350
|
+
// 2. indexOf would return -1, and indexOf('\n\n', -1) starts from 0
|
|
1351
|
+
// 3. This could find a \n\n inside a function body, inserting the import there!
|
|
1352
|
+
fileContent = newImport + '\n' + fileContent;
|
|
1353
|
+
}
|
|
837
1354
|
}
|
|
838
1355
|
}
|
|
839
1356
|
}
|
|
@@ -852,6 +1369,36 @@ export default async function writeScenarioComponents({
|
|
|
852
1369
|
);
|
|
853
1370
|
}
|
|
854
1371
|
|
|
1372
|
+
// Rewrite node_module imports that have universal mocks
|
|
1373
|
+
// Universal mocks create mock files at __codeyamMocks__/{safeFileName}.tsx
|
|
1374
|
+
// We need to rewrite imports like `import { logger } from "@formbricks/logger"`
|
|
1375
|
+
// to `import { logger } from "../__codeyamMocks__/_formbricks_logger"`
|
|
1376
|
+
const universalMocks = project.metadata?.universalMocks ?? [];
|
|
1377
|
+
const nodeModuleUniversalMocks = universalMocks.filter(
|
|
1378
|
+
(mock) => mock.nodeModule && mock.content,
|
|
1379
|
+
);
|
|
1380
|
+
|
|
1381
|
+
for (const universalMock of nodeModuleUniversalMocks) {
|
|
1382
|
+
const originalPath = universalMock.filePath;
|
|
1383
|
+
// Create the mock file name using the same safeFileName function as writeUniversalMocks
|
|
1384
|
+
const safeMockFileName = safeFileName(originalPath);
|
|
1385
|
+
const mockFileRelativePath = `${relativeMocksDir}/${safeMockFileName}`;
|
|
1386
|
+
|
|
1387
|
+
// Match both single and double quotes, and handle both named and default imports
|
|
1388
|
+
// Pattern 1: import { x, y } from "module"
|
|
1389
|
+
// Pattern 2: import x from "module"
|
|
1390
|
+
// Pattern 3: import * as x from "module"
|
|
1391
|
+
const importRegex = new RegExp(
|
|
1392
|
+
`(import\\s+(?:\\{[^}]*\\}|\\*\\s+as\\s+\\w+|\\w+)\\s+from\\s+)['"]${originalPath.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}['"]`,
|
|
1393
|
+
'g',
|
|
1394
|
+
);
|
|
1395
|
+
|
|
1396
|
+
fileContent = fileContent.replace(
|
|
1397
|
+
importRegex,
|
|
1398
|
+
`$1'${mockFileRelativePath}'`,
|
|
1399
|
+
);
|
|
1400
|
+
}
|
|
1401
|
+
|
|
855
1402
|
if (
|
|
856
1403
|
rootAnalysis.entitySha === entity.sha &&
|
|
857
1404
|
entity.metadata?.notExported &&
|
|
@@ -864,6 +1411,17 @@ export default async function writeScenarioComponents({
|
|
|
864
1411
|
}
|
|
865
1412
|
}
|
|
866
1413
|
|
|
1414
|
+
// When a default export is imported as named via re-export (e.g., index.tsx re-exports
|
|
1415
|
+
// a default export as named), we need to add a named export so the parent's
|
|
1416
|
+
// import statement works: `import { Name } from './path'`
|
|
1417
|
+
// The local variable name is the same as exportAsNamed (e.g., ScenarioEditor)
|
|
1418
|
+
if (exportAsNamed) {
|
|
1419
|
+
const namedExport = `export { ${exportAsNamed} };`;
|
|
1420
|
+
if (!fileContent.includes(namedExport)) {
|
|
1421
|
+
fileContent = `${fileContent}\n\n${namedExport}`;
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
|
|
867
1425
|
const basePath = safeFolder(file.path.split('/').slice(0, -1).join('/'));
|
|
868
1426
|
const extension = file.name.split('.').pop();
|
|
869
1427
|
// Include scenario name in path to allow multiple scenarios to coexist
|
|
@@ -882,6 +1440,10 @@ export default async function writeScenarioComponents({
|
|
|
882
1440
|
});
|
|
883
1441
|
}
|
|
884
1442
|
|
|
1443
|
+
// Strip <html> and <body> tags from root layout files for Next.js
|
|
1444
|
+
// These tags cause hydration errors when the scenario layout is nested under the real root
|
|
1445
|
+
fileContent = stripHtmlBodyTags(fileContent, file.path, framework);
|
|
1446
|
+
|
|
885
1447
|
// Rewrite asset imports (CSS, images, fonts, etc.) to correct relative paths
|
|
886
1448
|
// The original file path is relative to PROJECT_RELATIVE_PATH, the new path is scenarioComponentPath
|
|
887
1449
|
fileContent = rewriteAssetImports(
|
|
@@ -890,6 +1452,15 @@ export default async function writeScenarioComponents({
|
|
|
890
1452
|
scenarioComponentPath,
|
|
891
1453
|
);
|
|
892
1454
|
|
|
1455
|
+
// Rewrite relative TypeScript/JavaScript module imports to correct relative paths
|
|
1456
|
+
// This handles cases where the file is moved (e.g., from [environmentId]/ to _environmentId_/)
|
|
1457
|
+
// and relative imports like "./lib/organization" need to be rewritten
|
|
1458
|
+
fileContent = rewriteRelativeModuleImports(
|
|
1459
|
+
fileContent,
|
|
1460
|
+
`${PROJECT_RELATIVE_PATH}/${file.path}`,
|
|
1461
|
+
scenarioComponentPath,
|
|
1462
|
+
);
|
|
1463
|
+
|
|
893
1464
|
console.log(
|
|
894
1465
|
'Writing scenario component',
|
|
895
1466
|
file.path,
|
|
@@ -909,10 +1480,19 @@ export default async function writeScenarioComponents({
|
|
|
909
1480
|
// Scenario: ${scenario.id} - ${scenario.name}
|
|
910
1481
|
`;
|
|
911
1482
|
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
)
|
|
1483
|
+
// Use the directive that was extracted at the beginning of processing
|
|
1484
|
+
// This ensures it stays at the very top even after imports are prepended
|
|
1485
|
+
let finalContent: string;
|
|
1486
|
+
if (extractedDirective) {
|
|
1487
|
+
finalContent = `${extractedDirective}\n\n${scenarioComponentComment}\n\n${fileContent}`;
|
|
1488
|
+
console.log(
|
|
1489
|
+
`CodeYam: Placed "${extractedDirective}" directive at top of file: ${scenarioComponentPath}`,
|
|
1490
|
+
);
|
|
1491
|
+
} else {
|
|
1492
|
+
finalContent = `${scenarioComponentComment}\n\n${fileContent}`;
|
|
1493
|
+
}
|
|
1494
|
+
|
|
1495
|
+
await writeFile(scenarioComponentPath, finalContent);
|
|
916
1496
|
scenarioComponentPaths.push(scenarioComponentPath);
|
|
917
1497
|
|
|
918
1498
|
console.log('CodeYam [writeScenarioComponents]: Generated scenario files', {
|