create-appraisejs 0.1.10-alpha.8 → 0.2.0-alpha.1
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/README.md +52 -52
- package/dist/cli.e2e.test.d.ts +2 -0
- package/dist/cli.e2e.test.d.ts.map +1 -0
- package/dist/cli.e2e.test.js +73 -0
- package/dist/cli.e2e.test.js.map +1 -0
- package/dist/config.test.d.ts +2 -0
- package/dist/config.test.d.ts.map +1 -0
- package/dist/config.test.js +65 -0
- package/dist/config.test.js.map +1 -0
- package/dist/copy-template.test.d.ts +2 -0
- package/dist/copy-template.test.d.ts.map +1 -0
- package/dist/copy-template.test.js +71 -0
- package/dist/copy-template.test.js.map +1 -0
- package/dist/download-repo.test.d.ts +2 -0
- package/dist/download-repo.test.d.ts.map +1 -0
- package/dist/download-repo.test.js +14 -0
- package/dist/download-repo.test.js.map +1 -0
- package/dist/install.test.d.ts +2 -0
- package/dist/install.test.d.ts.map +1 -0
- package/dist/install.test.js +119 -0
- package/dist/install.test.js.map +1 -0
- package/dist/prepare-template-utils.d.ts.map +1 -1
- package/dist/prepare-template-utils.js +5 -0
- package/dist/prepare-template-utils.js.map +1 -1
- package/dist/prompts.test.d.ts +2 -0
- package/dist/prompts.test.d.ts.map +1 -0
- package/dist/prompts.test.js +58 -0
- package/dist/prompts.test.js.map +1 -0
- package/dist/scaffold-gitignore.d.ts +1 -0
- package/dist/scaffold-gitignore.d.ts.map +1 -1
- package/dist/scaffold-gitignore.js +3 -0
- package/dist/scaffold-gitignore.js.map +1 -1
- package/package.json +3 -2
- package/templates/default/.appraise-template-meta.json +2 -2
- package/templates/default/.env.example +2 -2
- package/templates/default/.vscode/settings.json +2 -1
- package/templates/default/README.md +53 -53
- package/templates/default/automation/mapping/locator-map.json +1 -14
- package/templates/default/automation/steps/actions/click.step.ts +58 -58
- package/templates/default/automation/steps/actions/hover.step.ts +27 -27
- package/templates/default/automation/steps/actions/input.step.ts +84 -84
- package/templates/default/automation/steps/actions/navigation.step.ts +70 -70
- package/templates/default/automation/steps/actions/random_data.step.ts +142 -142
- package/templates/default/automation/steps/actions/store.step.ts +86 -86
- package/templates/default/automation/steps/actions/wait.step.ts +90 -90
- package/templates/default/automation/steps/validations/active_state_assertion.step.ts +30 -30
- package/templates/default/automation/steps/validations/navigation_assertion.step.ts +22 -22
- package/templates/default/automation/steps/validations/text_assertion.step.ts +107 -107
- package/templates/default/automation/steps/validations/visibility_assertion.step.ts +26 -26
- package/templates/default/components.json +24 -24
- package/templates/default/cucumber.mjs +16 -16
- package/templates/default/eslint.config.mjs +16 -16
- package/templates/default/gitignore +3 -0
- package/templates/default/next-env.d.ts +6 -6
- package/templates/default/next.config.ts +11 -11
- package/templates/default/package-lock.json +146 -75
- package/templates/default/package.json +2 -1
- package/templates/default/packages/cucumber-runtime/package.json +13 -13
- package/templates/default/packages/cucumber-runtime/src/cache.util.ts +93 -93
- package/templates/default/packages/cucumber-runtime/src/cli.ts +68 -68
- package/templates/default/packages/cucumber-runtime/src/environment.util.ts +21 -21
- package/templates/default/packages/cucumber-runtime/src/executor.ts +32 -32
- package/templates/default/packages/cucumber-runtime/src/hooks.ts +25 -3
- package/templates/default/packages/cucumber-runtime/src/index.ts +17 -17
- package/templates/default/packages/cucumber-runtime/src/locator.util.ts +234 -234
- package/templates/default/packages/cucumber-runtime/src/parameter-types.ts +7 -7
- package/templates/default/packages/cucumber-runtime/src/paths.ts +66 -1
- package/templates/default/packages/cucumber-runtime/src/random-data.util.ts +35 -35
- package/templates/default/packages/cucumber-runtime/src/types.ts +13 -13
- package/templates/default/packages/cucumber-runtime/src/world.ts +44 -44
- package/templates/default/packages/cucumber-runtime/tsconfig.json +11 -11
- package/templates/default/packages/locator-picker-companion/dist/cli.d.ts +1 -0
- package/templates/default/packages/locator-picker-companion/dist/cli.js +302 -0
- package/templates/default/packages/locator-picker-companion/dist/index.d.ts +3 -0
- package/templates/default/packages/locator-picker-companion/dist/index.js +3 -0
- package/templates/default/packages/locator-picker-companion/dist/injected-picker-script.d.ts +1 -0
- package/templates/default/packages/locator-picker-companion/dist/injected-picker-script.js +615 -0
- package/templates/default/packages/locator-picker-companion/dist/launcher.d.ts +11 -0
- package/templates/default/packages/locator-picker-companion/dist/launcher.js +59 -0
- package/templates/default/packages/locator-picker-companion/dist/selector-generator.d.ts +3 -0
- package/templates/default/packages/locator-picker-companion/dist/selector-generator.js +257 -0
- package/templates/default/packages/locator-picker-companion/dist/session-file.d.ts +22 -0
- package/templates/default/packages/locator-picker-companion/dist/session-file.js +150 -0
- package/templates/default/packages/locator-picker-companion/dist/types.d.ts +31 -0
- package/templates/default/packages/locator-picker-companion/dist/types.js +1 -0
- package/templates/default/packages/locator-picker-companion/package.json +17 -0
- package/templates/default/packages/locator-picker-companion/src/cli.ts +428 -0
- package/templates/default/packages/locator-picker-companion/src/index.ts +3 -0
- package/templates/default/packages/locator-picker-companion/src/injected-picker-script.ts +771 -0
- package/templates/default/packages/locator-picker-companion/src/launcher.ts +77 -0
- package/templates/default/packages/locator-picker-companion/src/selector-generator.ts +339 -0
- package/templates/default/packages/locator-picker-companion/src/session-file.ts +226 -0
- package/templates/default/packages/locator-picker-companion/src/types.ts +42 -0
- package/templates/default/packages/locator-picker-companion/tsconfig.json +14 -0
- package/templates/default/postcss.config.mjs +8 -8
- package/templates/default/prisma/dev.db +0 -0
- package/templates/default/prisma/migrations/20251104113456_add_type_for_template_step_groups/migration.sql +16 -16
- package/templates/default/prisma/migrations/20251104170946_add_tags_to_test_suite_and_test_case/migration.sql +27 -27
- package/templates/default/prisma/migrations/20251112190024_add_cascade_delete_to_test_run_test_case/migration.sql +17 -17
- package/templates/default/prisma/migrations/20251113181100_add_test_run_log/migration.sql +12 -12
- package/templates/default/prisma/migrations/20251119191838_add_tag_type/migration.sql +28 -28
- package/templates/default/prisma/migrations/20251121164059_add_conflict_resolution/migration.sql +12 -12
- package/templates/default/prisma/migrations/20251223183400_add_report_model_to_db_schema/migration.sql +10 -10
- package/templates/default/prisma/migrations/20251223183637_add_report_test_case_entity_for_storing_test_results_for_individual_test_cases/migration.sql +10 -10
- package/templates/default/prisma/migrations/20251224083549_add_comprehensive_report_storage/migration.sql +108 -108
- package/templates/default/prisma/migrations/20251229194422_migrate_duration_to_string/migration.sql +55 -55
- package/templates/default/prisma/migrations/20251230124637_add_unique_constraint_to_test_run_name/migration.sql +27 -27
- package/templates/default/prisma/migrations/20260115094436_add_dashboard_metrics/migration.sql +59 -59
- package/templates/default/prisma/migrations/20260127172022_add_cascade_delete_to_step_parameters/migration.sql +34 -34
- package/templates/default/prisma/migrations/20260313093000_add_report_step_screenshot_path/migration.sql +1 -0
- package/templates/default/prisma/migrations/20260318120000_add_test_suite_context_to_test_run_test_case/migration.sql +20 -0
- package/templates/default/prisma/migrations/20260318173512_add_support_of_test_suite_level_runs/migration.sql +2 -0
- package/templates/default/prisma/schema.prisma +4 -0
- package/templates/default/scripts/install-playwright.ts +20 -0
- package/templates/default/scripts/protect-seeded-files.ts +38 -38
- package/templates/default/scripts/regenerate-features.ts +94 -94
- package/templates/default/scripts/setup-env.ts +19 -19
- package/templates/default/scripts/sync-all.ts +22 -66
- package/templates/default/scripts/sync-appraise-base-template.ts +57 -19
- package/templates/default/scripts/sync-environments.ts +40 -21
- package/templates/default/scripts/sync-locator-groups.ts +410 -410
- package/templates/default/scripts/sync-locators.ts +398 -398
- package/templates/default/scripts/sync-modules.ts +341 -341
- package/templates/default/scripts/sync-tags.ts +2 -3
- package/templates/default/scripts/sync-template-step-groups.ts +0 -3
- package/templates/default/scripts/sync-template-steps.ts +37 -11
- package/templates/default/scripts/sync-test-cases.ts +68 -16
- package/templates/default/scripts/sync-test-suites.ts +7 -5
- package/templates/default/src/actions/conflict/conflict.action.ts +33 -33
- package/templates/default/src/actions/dashboard/dashboard-actions.ts +240 -240
- package/templates/default/src/actions/environments/environment-actions.ts +188 -188
- package/templates/default/src/actions/locator/locator-actions.ts +490 -490
- package/templates/default/src/actions/locator-groups/locator-group-actions.ts +6 -3
- package/templates/default/src/actions/locator-picker/locator-picker-actions.ts +243 -0
- package/templates/default/src/actions/modules/module-actions.ts +135 -135
- package/templates/default/src/actions/reports/report-actions.ts +51 -49
- package/templates/default/src/actions/review/review-actions.ts +147 -147
- package/templates/default/src/actions/settings/sync-actions.ts +46 -0
- package/templates/default/src/actions/tags/tag-actions.ts +107 -107
- package/templates/default/src/actions/template-step/template-step-actions.ts +38 -4
- package/templates/default/src/actions/template-step-group/template-step-group-actions.ts +10 -3
- package/templates/default/src/actions/template-test-case/template-test-case-actions.ts +238 -238
- package/templates/default/src/actions/test-case/test-case-actions.ts +356 -356
- package/templates/default/src/actions/test-run/test-run-actions.ts +222 -129
- package/templates/default/src/actions/test-suite/test-suite-actions.ts +95 -17
- package/templates/default/src/actions/user/user-actions.ts +13 -13
- package/templates/default/src/app/(base)/environments/create/page.tsx +28 -28
- package/templates/default/src/app/(base)/environments/environment-form.tsx +219 -219
- package/templates/default/src/app/(base)/environments/environment-table-columns.tsx +96 -96
- package/templates/default/src/app/(base)/environments/environment-table.tsx +24 -24
- package/templates/default/src/app/(base)/environments/modify/[id]/page.tsx +46 -46
- package/templates/default/src/app/(base)/environments/page.tsx +59 -59
- package/templates/default/src/app/(base)/layout.tsx +10 -10
- package/templates/default/src/app/(base)/locator-groups/create/page.tsx +44 -44
- package/templates/default/src/app/(base)/locator-groups/locator-group-form.tsx +215 -215
- package/templates/default/src/app/(base)/locator-groups/locator-group-table-columns.tsx +77 -77
- package/templates/default/src/app/(base)/locator-groups/locator-group-table.tsx +28 -28
- package/templates/default/src/app/(base)/locator-groups/modify/[id]/page.tsx +46 -46
- package/templates/default/src/app/(base)/locator-groups/page.tsx +20 -8
- package/templates/default/src/app/(base)/locators/create/create-locator-workspace.tsx +542 -0
- package/templates/default/src/app/(base)/locators/create/page.tsx +32 -19
- package/templates/default/src/app/(base)/locators/locator-form.tsx +163 -163
- package/templates/default/src/app/(base)/locators/locator-table-columns.tsx +73 -73
- package/templates/default/src/app/(base)/locators/locator-table.tsx +28 -28
- package/templates/default/src/app/(base)/locators/modify/[id]/page.tsx +56 -27
- package/templates/default/src/app/(base)/locators/page.tsx +13 -13
- package/templates/default/src/app/(base)/locators/picker/page.tsx +7 -0
- package/templates/default/src/app/(base)/locators/sync-locators-button.tsx +66 -66
- package/templates/default/src/app/(base)/modules/create/page.tsx +34 -34
- package/templates/default/src/app/(base)/modules/modify/[id]/page.tsx +46 -46
- package/templates/default/src/app/(base)/modules/module-form.tsx +126 -126
- package/templates/default/src/app/(base)/modules/module-table-columns.tsx +85 -85
- package/templates/default/src/app/(base)/modules/module-table.tsx +24 -24
- package/templates/default/src/app/(base)/modules/page.tsx +59 -59
- package/templates/default/src/app/(base)/reports/[id]/page.tsx +40 -33
- package/templates/default/src/app/(base)/reports/duration-chart.tsx +33 -33
- package/templates/default/src/app/(base)/reports/feature-chart.tsx +78 -78
- package/templates/default/src/app/(base)/reports/overview-chart.tsx +49 -46
- package/templates/default/src/app/(base)/reports/page.tsx +98 -98
- package/templates/default/src/app/(base)/reports/report-metric-card.tsx +78 -16
- package/templates/default/src/app/(base)/reports/report-table-columns.tsx +189 -189
- package/templates/default/src/app/(base)/reports/report-table.tsx +72 -72
- package/templates/default/src/app/(base)/reports/report-view-table-columns.tsx +12 -1
- package/templates/default/src/app/(base)/reports/report-view-table.tsx +1 -0
- package/templates/default/src/app/(base)/reports/test-cases/page.tsx +40 -42
- package/templates/default/src/app/(base)/reports/test-cases/test-cases-metric-table-columns.tsx +115 -115
- package/templates/default/src/app/(base)/reports/test-cases/test-cases-metric-table.tsx +27 -27
- package/templates/default/src/app/(base)/reports/test-suites/page.tsx +42 -42
- package/templates/default/src/app/(base)/reports/test-suites/test-suites-metric-table-columns.tsx +79 -79
- package/templates/default/src/app/(base)/reports/test-suites/test-suites-metric-table.tsx +27 -27
- package/templates/default/src/app/(base)/reports/view-logs-button.tsx +58 -60
- package/templates/default/src/app/(base)/reviews/create/page.tsx +26 -26
- package/templates/default/src/app/(base)/reviews/created-reviews-table.tsx +15 -15
- package/templates/default/src/app/(base)/reviews/modify/[id]/page.tsx +26 -26
- package/templates/default/src/app/(base)/reviews/page.tsx +26 -26
- package/templates/default/src/app/(base)/reviews/review/[id]/page.tsx +26 -26
- package/templates/default/src/app/(base)/reviews/review-form.tsx +11 -11
- package/templates/default/src/app/(base)/reviews/review-table-by-creator-columns.tsx +9 -9
- package/templates/default/src/app/(base)/reviews/review-table-by-reviewer-columns.tsx +9 -9
- package/templates/default/src/app/(base)/reviews/reviewer-reviews-table.tsx +15 -15
- package/templates/default/src/app/(base)/settings/page.tsx +30 -0
- package/templates/default/src/app/(base)/settings/settings-sync-panel.tsx +261 -0
- package/templates/default/src/app/(base)/tags/create/page.tsx +39 -39
- package/templates/default/src/app/(base)/tags/modify/[id]/page.tsx +50 -50
- package/templates/default/src/app/(base)/tags/page.tsx +58 -58
- package/templates/default/src/app/(base)/tags/tag-form.tsx +147 -147
- package/templates/default/src/app/(base)/tags/tag-table-columns.tsx +63 -63
- package/templates/default/src/app/(base)/tags/tag-table.tsx +29 -29
- package/templates/default/src/app/(base)/template-step-groups/create/page.tsx +28 -28
- package/templates/default/src/app/(base)/template-step-groups/modify/[id]/page.tsx +45 -45
- package/templates/default/src/app/(base)/template-step-groups/page.tsx +60 -60
- package/templates/default/src/app/(base)/template-step-groups/template-step-group-form.tsx +167 -167
- package/templates/default/src/app/(base)/template-step-groups/template-step-group-table-columns.tsx +89 -89
- package/templates/default/src/app/(base)/template-step-groups/template-step-group-table.tsx +32 -32
- package/templates/default/src/app/(base)/template-steps/create/page.tsx +37 -37
- package/templates/default/src/app/(base)/template-steps/modify/[id]/page.tsx +49 -49
- package/templates/default/src/app/(base)/template-steps/page.tsx +58 -58
- package/templates/default/src/app/(base)/template-steps/paramChip.tsx +213 -213
- package/templates/default/src/app/(base)/template-steps/template-step-form.tsx +384 -384
- package/templates/default/src/app/(base)/template-steps/template-step-table-columns.tsx +158 -158
- package/templates/default/src/app/(base)/template-steps/template-step-table.tsx +24 -24
- package/templates/default/src/app/(base)/template-test-cases/create/page.tsx +56 -56
- package/templates/default/src/app/(base)/template-test-cases/modify/[id]/page.tsx +89 -89
- package/templates/default/src/app/(base)/template-test-cases/page.tsx +58 -58
- package/templates/default/src/app/(base)/template-test-cases/template-test-case-flow.tsx +84 -84
- package/templates/default/src/app/(base)/template-test-cases/template-test-case-form.tsx +262 -262
- package/templates/default/src/app/(base)/template-test-cases/template-test-case-table-columns.tsx +76 -76
- package/templates/default/src/app/(base)/template-test-cases/template-test-case-table.tsx +32 -32
- package/templates/default/src/app/(base)/test-cases/create/page.tsx +76 -76
- package/templates/default/src/app/(base)/test-cases/create-from-template/generate/[id]/page.tsx +96 -96
- package/templates/default/src/app/(base)/test-cases/create-from-template/page.tsx +38 -38
- package/templates/default/src/app/(base)/test-cases/create-from-template/template-selection-form.tsx +73 -73
- package/templates/default/src/app/(base)/test-cases/modify/[id]/page.tsx +106 -106
- package/templates/default/src/app/(base)/test-cases/page.tsx +2 -2
- package/templates/default/src/app/(base)/test-cases/test-case-flow.tsx +82 -82
- package/templates/default/src/app/(base)/test-cases/test-case-form.tsx +395 -395
- package/templates/default/src/app/(base)/test-cases/test-case-table-columns.tsx +6 -71
- package/templates/default/src/app/(base)/test-cases/test-case-table.tsx +2 -2
- package/templates/default/src/app/(base)/test-runs/[id]/page.tsx +4 -1
- package/templates/default/src/app/(base)/test-runs/create/page.tsx +11 -9
- package/templates/default/src/app/(base)/test-runs/page.tsx +60 -60
- package/templates/default/src/app/(base)/test-runs/test-run-form.tsx +37 -44
- package/templates/default/src/app/(base)/test-runs/test-run-table-columns.tsx +229 -229
- package/templates/default/src/app/(base)/test-runs/test-run-table.tsx +127 -127
- package/templates/default/src/app/(base)/test-suites/create/page.tsx +3 -2
- package/templates/default/src/app/(base)/test-suites/modify/[id]/page.tsx +2 -1
- package/templates/default/src/app/(base)/test-suites/page.tsx +57 -21
- package/templates/default/src/app/(base)/test-suites/test-suite-form.tsx +16 -17
- package/templates/default/src/app/(base)/test-suites/test-suite-table-columns.tsx +2 -1
- package/templates/default/src/app/(base)/test-suites/test-suite-table.tsx +29 -29
- package/templates/default/src/app/(dashboard-components)/app-drawer.tsx +187 -187
- package/templates/default/src/app/(dashboard-components)/data-card-grid.tsx +12 -12
- package/templates/default/src/app/(dashboard-components)/data-card.tsx +26 -26
- package/templates/default/src/app/(dashboard-components)/execution-health-panel.tsx +56 -56
- package/templates/default/src/app/(dashboard-components)/ongoing-test-runs-card.tsx +87 -87
- package/templates/default/src/app/(dashboard-components)/quick-actions-drawer.tsx +44 -44
- package/templates/default/src/app/api/reports/steps/[stepId]/screenshot/route.ts +52 -0
- package/templates/default/src/app/api/test-runs/[runId]/download/route.ts +97 -34
- package/templates/default/src/app/api/test-runs/[runId]/logs/route.ts +4 -1
- package/templates/default/src/app/api/test-runs/[runId]/trace/[testCaseId]/route.ts +146 -147
- package/templates/default/src/app/globals.css +147 -147
- package/templates/default/src/app/layout.tsx +4 -0
- package/templates/default/src/app/page.tsx +2 -0
- package/templates/default/src/assets/icons/empty-tube.tsx +23 -23
- package/templates/default/src/assets/icons/tube-plus.tsx +29 -29
- package/templates/default/src/components/base-node.tsx +21 -21
- package/templates/default/src/components/chart/pie-chart.tsx +73 -73
- package/templates/default/src/components/data-extraction/locator-inspector.tsx +460 -460
- package/templates/default/src/components/data-state/empty-state.tsx +40 -40
- package/templates/default/src/components/data-visualization/info-card.tsx +70 -70
- package/templates/default/src/components/data-visualization/info-grid.tsx +22 -22
- package/templates/default/src/components/diagram/button-edge.tsx +54 -54
- package/templates/default/src/components/diagram/dynamic-parameters.tsx +474 -474
- package/templates/default/src/components/diagram/edit-header-option.tsx +36 -36
- package/templates/default/src/components/diagram/flow-diagram.tsx +470 -470
- package/templates/default/src/components/diagram/node-form.tsx +262 -262
- package/templates/default/src/components/diagram/options-header-node.tsx +57 -57
- package/templates/default/src/components/diagram/template-step-combobox.tsx +155 -155
- package/templates/default/src/components/form/error-message.tsx +7 -7
- package/templates/default/src/components/kokonutui/smooth-tab.tsx +453 -453
- package/templates/default/src/components/loading-skeleton/data-table/data-table-skeleton.tsx +30 -30
- package/templates/default/src/components/loading-skeleton/form/button-skeleton.tsx +8 -8
- package/templates/default/src/components/loading-skeleton/form/icon-button-skeleton.tsx +8 -8
- package/templates/default/src/components/loading-skeleton/form/text-input-skeleton.tsx +8 -8
- package/templates/default/src/components/loading-skeleton/visualization/table-skeleton.tsx +14 -14
- package/templates/default/src/components/logo.tsx +15 -15
- package/templates/default/src/components/navigation/command-badge.tsx +34 -34
- package/templates/default/src/components/navigation/command-chain-input.tsx +51 -51
- package/templates/default/src/components/navigation/entity-search-command.tsx +116 -116
- package/templates/default/src/components/navigation/nav-card.tsx +31 -31
- package/templates/default/src/components/navigation/nav-command.tsx +13 -0
- package/templates/default/src/components/navigation/nav-link.tsx +60 -60
- package/templates/default/src/components/navigation/nav-menu-card-deck.tsx +112 -112
- package/templates/default/src/components/node-header.tsx +159 -159
- package/templates/default/src/components/reports/test-case-logs-modal.tsx +310 -253
- package/templates/default/src/components/table/table-actions.tsx +172 -172
- package/templates/default/src/components/test-case/test-case-columns.tsx +76 -0
- package/templates/default/src/components/test-case/test-case-picker.tsx +244 -0
- package/templates/default/src/components/test-run/download-logs-button.tsx +92 -99
- package/templates/default/src/components/test-run/log-viewer.tsx +1 -14
- package/templates/default/src/components/test-run/test-run-details.tsx +15 -2
- package/templates/default/src/components/test-run/test-run-header.tsx +149 -149
- package/templates/default/src/components/test-run/view-report-button.tsx +102 -102
- package/templates/default/src/components/test-suite/test-suite-picker.tsx +444 -0
- package/templates/default/src/components/theme/mode-toggle.tsx +54 -54
- package/templates/default/src/components/theme/theme-provider.tsx +8 -8
- package/templates/default/src/components/typography/page-header-subtitle.tsx +7 -7
- package/templates/default/src/components/typography/page-header.tsx +7 -7
- package/templates/default/src/components/ui/alert-dialog.tsx +106 -106
- package/templates/default/src/components/ui/alert.tsx +43 -43
- package/templates/default/src/components/ui/avatar.tsx +40 -40
- package/templates/default/src/components/ui/badge.tsx +29 -29
- package/templates/default/src/components/ui/button.tsx +47 -47
- package/templates/default/src/components/ui/calendar.tsx +158 -158
- package/templates/default/src/components/ui/card.tsx +43 -43
- package/templates/default/src/components/ui/checkbox.tsx +28 -28
- package/templates/default/src/components/ui/command.tsx +135 -135
- package/templates/default/src/components/ui/data-table-column-header.tsx +61 -61
- package/templates/default/src/components/ui/data-table-pagination.tsx +87 -87
- package/templates/default/src/components/ui/data-table-view-options.tsx +50 -50
- package/templates/default/src/components/ui/data-table.tsx +261 -261
- package/templates/default/src/components/ui/dialog.tsx +97 -97
- package/templates/default/src/components/ui/dropdown-menu.tsx +182 -182
- package/templates/default/src/components/ui/input.tsx +22 -22
- package/templates/default/src/components/ui/kbd.tsx +28 -28
- package/templates/default/src/components/ui/label.tsx +19 -19
- package/templates/default/src/components/ui/loading.tsx +12 -12
- package/templates/default/src/components/ui/multi-select-with-preview.tsx +116 -116
- package/templates/default/src/components/ui/multi-select.tsx +142 -142
- package/templates/default/src/components/ui/navigation-menu.tsx +120 -120
- package/templates/default/src/components/ui/popover.tsx +33 -33
- package/templates/default/src/components/ui/progress.tsx +25 -25
- package/templates/default/src/components/ui/radio-group.tsx +44 -44
- package/templates/default/src/components/ui/scroll-area.tsx +40 -40
- package/templates/default/src/components/ui/select.tsx +151 -151
- package/templates/default/src/components/ui/separator.tsx +22 -22
- package/templates/default/src/components/ui/skeleton.tsx +7 -7
- package/templates/default/src/components/ui/table.tsx +76 -76
- package/templates/default/src/components/ui/tabs.tsx +55 -55
- package/templates/default/src/components/ui/textarea.tsx +21 -21
- package/templates/default/src/components/ui/toast.tsx +113 -113
- package/templates/default/src/components/ui/toaster.tsx +26 -26
- package/templates/default/src/components/user-prompt/delete-prompt.tsx +87 -87
- package/templates/default/src/config/db-config.ts +10 -10
- package/templates/default/src/constants/form-opts/diagram/node-form.ts +30 -30
- package/templates/default/src/constants/form-opts/environment-form-opts.ts +24 -24
- package/templates/default/src/constants/form-opts/locator-form-opts.ts +20 -20
- package/templates/default/src/constants/form-opts/locator-group-form-opts.ts +28 -28
- package/templates/default/src/constants/form-opts/module-form-opts.ts +21 -21
- package/templates/default/src/constants/form-opts/review-form-opts.ts +23 -23
- package/templates/default/src/constants/form-opts/tag-form-opts.ts +42 -42
- package/templates/default/src/constants/form-opts/template-selection-form-opts.ts +16 -16
- package/templates/default/src/constants/form-opts/template-step-group-form-opts.ts +24 -24
- package/templates/default/src/constants/form-opts/template-test-case-form-opts.ts +39 -39
- package/templates/default/src/constants/form-opts/template-test-step-form-opts.ts +36 -36
- package/templates/default/src/constants/form-opts/test-case-form-opts.ts +43 -43
- package/templates/default/src/constants/form-opts/test-run-form-opts.ts +5 -3
- package/templates/default/src/constants/form-opts/test-suite-form-opts.ts +24 -24
- package/templates/default/src/hooks/use-toast.ts +187 -187
- package/templates/default/src/lib/automation/paths.ts +42 -12
- package/templates/default/src/lib/automation/projection-service.ts +2 -1
- package/templates/default/src/lib/bidirectional-sync.ts +432 -432
- package/templates/default/src/lib/database-sync.ts +2 -7
- package/templates/default/src/lib/environment-file-utils.ts +184 -184
- package/templates/default/src/lib/executor/local-executor-adapter.ts +24 -25
- package/templates/default/src/lib/executor/types.ts +2 -2
- package/templates/default/src/lib/feature-file-generator.ts +5 -66
- package/templates/default/src/lib/gherkin-parser.ts +259 -259
- package/templates/default/src/lib/locator-group-file-utils.ts +307 -307
- package/templates/default/src/lib/locator-picker/session-manager.ts +452 -0
- package/templates/default/src/lib/locator-picker/suggestions.ts +124 -0
- package/templates/default/src/lib/metrics/metric-calculator.ts +5 -0
- package/templates/default/src/lib/module-hierarchy-builder.ts +205 -205
- package/templates/default/src/lib/path-helpers/module-path.ts +71 -71
- package/templates/default/src/lib/process/task-spawner.ts +39 -2
- package/templates/default/src/lib/sync/projected-feature-utils.ts +113 -0
- package/templates/default/src/lib/sync/sync-executor.ts +130 -0
- package/templates/default/src/lib/sync/sync-pending-counts.test.ts +239 -0
- package/templates/default/src/lib/sync/sync-pending-counts.ts +1358 -0
- package/templates/default/src/lib/sync/sync-registry.ts +149 -0
- package/templates/default/src/lib/tag-utils.ts +28 -0
- package/templates/default/src/lib/template-sync-utils.d.ts +6 -6
- package/templates/default/src/lib/template-sync-utils.js +46 -46
- package/templates/default/src/lib/template-sync-utils.ts +63 -63
- package/templates/default/src/lib/test-case-utils.ts +6 -6
- package/templates/default/src/lib/test-run/log-formatter.ts +83 -83
- package/templates/default/src/lib/test-run/matching.ts +117 -0
- package/templates/default/src/lib/test-run/process-manager.ts +2 -0
- package/templates/default/src/lib/test-run/report-parser.ts +352 -316
- package/templates/default/src/lib/test-run/test-run-executor.ts +13 -15
- package/templates/default/src/lib/test-run/winston-logger.ts +64 -66
- package/templates/default/src/lib/test-suite-identifier-service.ts +76 -0
- package/templates/default/src/lib/test-suite-utils.ts +6 -0
- package/templates/default/src/lib/transformers/gherkin-converter.ts +42 -42
- package/templates/default/src/lib/transformers/key-to-icon-transformer.tsx +95 -95
- package/templates/default/src/lib/transformers/template-test-case-converter.ts +160 -160
- package/templates/default/src/lib/utils/node-param-validation.ts +81 -81
- package/templates/default/src/lib/utils/template-step-file-generator.ts +104 -104
- package/templates/default/src/lib/utils/template-step-file-manager-intelligent.ts +0 -8
- package/templates/default/src/lib/utils/template-step-file-manager.ts +166 -166
- package/templates/default/src/lib/utils.ts +31 -31
- package/templates/default/src/types/diagram/diagram.ts +34 -34
- package/templates/default/src/types/diagram/template-step.ts +11 -11
- package/templates/default/src/types/executor/browser.type.ts +1 -1
- package/templates/default/src/types/form/actionHandler.ts +6 -6
- package/templates/default/src/types/locator/locator.type.ts +11 -11
- package/templates/default/src/types/locator-picker.ts +65 -0
- package/templates/default/src/types/step/step.type.ts +1 -1
- package/templates/default/src/types/table/data-table.ts +6 -6
- package/templates/default/src/types/test-case-picker.ts +6 -0
- package/templates/default/src/types/test-suite-picker.ts +18 -0
- package/templates/default/tailwind.config.ts +62 -62
- package/templates/default/tsconfig.json +4 -1
- package/templates/default/appraisejs.config.json +0 -1
|
@@ -1,205 +1,205 @@
|
|
|
1
|
-
import prisma from '@/config/db-config'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Represents a module path structure
|
|
5
|
-
*/
|
|
6
|
-
export interface ModulePath {
|
|
7
|
-
path: string
|
|
8
|
-
name: string
|
|
9
|
-
parentPath?: string
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Creates or finds a module by its path
|
|
14
|
-
* @param modulePath - The module path (e.g., "/module1/submodule")
|
|
15
|
-
* @param moduleName - The name of the module
|
|
16
|
-
* @param parentId - Optional parent module ID
|
|
17
|
-
* @returns Promise<string> - The ID of the created or found module
|
|
18
|
-
*/
|
|
19
|
-
export async function createOrFindModule(modulePath: string, moduleName: string, parentId?: string): Promise<string> {
|
|
20
|
-
try {
|
|
21
|
-
// First, try to find existing module by name and parent
|
|
22
|
-
const existingModule = await prisma.module.findFirst({
|
|
23
|
-
where: {
|
|
24
|
-
name: moduleName,
|
|
25
|
-
parentId: parentId || null,
|
|
26
|
-
},
|
|
27
|
-
})
|
|
28
|
-
|
|
29
|
-
if (existingModule) {
|
|
30
|
-
return existingModule.id
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// Create new module
|
|
34
|
-
const newModule = await prisma.module.create({
|
|
35
|
-
data: {
|
|
36
|
-
name: moduleName,
|
|
37
|
-
parentId: parentId || null,
|
|
38
|
-
// Add description only if it's required by the schema
|
|
39
|
-
// For now, we'll leave it empty since it's optional
|
|
40
|
-
},
|
|
41
|
-
})
|
|
42
|
-
|
|
43
|
-
console.log(`Created module: ${moduleName} (${modulePath})`)
|
|
44
|
-
return newModule.id
|
|
45
|
-
} catch (error) {
|
|
46
|
-
console.error(`Error creating module ${moduleName}:`, error)
|
|
47
|
-
throw error
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Builds the complete module hierarchy from a module path
|
|
53
|
-
* @param modulePath - The module path (e.g., "/module1/submodule")
|
|
54
|
-
* @returns Promise<string> - The ID of the leaf module
|
|
55
|
-
*/
|
|
56
|
-
export async function buildModuleHierarchy(modulePath: string): Promise<string> {
|
|
57
|
-
try {
|
|
58
|
-
// Parse the module path
|
|
59
|
-
const pathParts = modulePath.split('/').filter(part => part && part !== '')
|
|
60
|
-
|
|
61
|
-
// Handle empty path (root level) - create/find a default root module
|
|
62
|
-
if (pathParts.length === 0) {
|
|
63
|
-
const rootModule = await prisma.module.findFirst({
|
|
64
|
-
where: {
|
|
65
|
-
name: 'root',
|
|
66
|
-
parentId: null,
|
|
67
|
-
},
|
|
68
|
-
})
|
|
69
|
-
|
|
70
|
-
if (rootModule) {
|
|
71
|
-
return rootModule.id
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// Create default root module
|
|
75
|
-
const newRootModule = await prisma.module.create({
|
|
76
|
-
data: {
|
|
77
|
-
name: 'root',
|
|
78
|
-
parentId: null,
|
|
79
|
-
},
|
|
80
|
-
})
|
|
81
|
-
|
|
82
|
-
console.log(`Created root module for features without module path`)
|
|
83
|
-
return newRootModule.id
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
let currentParentId: string | undefined
|
|
87
|
-
let currentPath = ''
|
|
88
|
-
|
|
89
|
-
// Create or find each module in the hierarchy
|
|
90
|
-
for (let i = 0; i < pathParts.length; i++) {
|
|
91
|
-
const moduleName = pathParts[i]
|
|
92
|
-
currentPath += `/${moduleName}`
|
|
93
|
-
|
|
94
|
-
const moduleId = await createOrFindModule(currentPath, moduleName, currentParentId)
|
|
95
|
-
|
|
96
|
-
currentParentId = moduleId
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
return currentParentId!
|
|
100
|
-
} catch (error) {
|
|
101
|
-
console.error(`Error building module hierarchy for path ${modulePath}:`, error)
|
|
102
|
-
throw error
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Gets all existing modules as a flat list with their paths
|
|
108
|
-
* @returns Promise<Array<{id: string, name: string, path: string, parentId: string | null}>>
|
|
109
|
-
*/
|
|
110
|
-
export async function getAllModulesWithPaths(): Promise<
|
|
111
|
-
Array<{
|
|
112
|
-
id: string
|
|
113
|
-
name: string
|
|
114
|
-
path: string
|
|
115
|
-
parentId: string | null
|
|
116
|
-
}>
|
|
117
|
-
> {
|
|
118
|
-
try {
|
|
119
|
-
const modules = await prisma.module.findMany({
|
|
120
|
-
orderBy: [{ parentId: 'asc' }, { name: 'asc' }],
|
|
121
|
-
})
|
|
122
|
-
|
|
123
|
-
// Build paths for each module
|
|
124
|
-
const modulesWithPaths = modules.map(module => {
|
|
125
|
-
const path = buildModulePath(modules, module)
|
|
126
|
-
return {
|
|
127
|
-
id: module.id,
|
|
128
|
-
name: module.name,
|
|
129
|
-
path,
|
|
130
|
-
parentId: module.parentId,
|
|
131
|
-
}
|
|
132
|
-
})
|
|
133
|
-
|
|
134
|
-
return modulesWithPaths
|
|
135
|
-
} catch (error) {
|
|
136
|
-
console.error('Error fetching modules with paths:', error)
|
|
137
|
-
throw error
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* Builds the full path for a module based on its hierarchy
|
|
143
|
-
* @param allModules - All modules from the database
|
|
144
|
-
* @param targetModule - The module to build the path for
|
|
145
|
-
* @returns string - The full module path
|
|
146
|
-
*/
|
|
147
|
-
function buildModulePath(
|
|
148
|
-
allModules: Array<{ id: string; name: string; parentId: string | null }>,
|
|
149
|
-
targetModule: { id: string; name: string; parentId: string | null },
|
|
150
|
-
): string {
|
|
151
|
-
const pathParts: string[] = []
|
|
152
|
-
let currentModule = targetModule
|
|
153
|
-
|
|
154
|
-
// Traverse up the hierarchy
|
|
155
|
-
while (currentModule) {
|
|
156
|
-
pathParts.unshift(currentModule.name)
|
|
157
|
-
|
|
158
|
-
if (currentModule.parentId) {
|
|
159
|
-
currentModule = allModules.find(m => m.id === currentModule.parentId)!
|
|
160
|
-
if (!currentModule) break
|
|
161
|
-
} else {
|
|
162
|
-
break
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
return '/' + pathParts.join('/')
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* Finds a module by its path
|
|
171
|
-
* @param modulePath - The module path to find
|
|
172
|
-
* @returns Promise<string | null> - The module ID or null if not found
|
|
173
|
-
*/
|
|
174
|
-
export async function findModuleByPath(modulePath: string): Promise<string | null> {
|
|
175
|
-
try {
|
|
176
|
-
const modules = await prisma.module.findMany()
|
|
177
|
-
const pathParts = modulePath.split('/').filter(part => part && part !== '')
|
|
178
|
-
|
|
179
|
-
if (pathParts.length === 0) {
|
|
180
|
-
return null
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
// Find the root module
|
|
184
|
-
let currentModule = modules.find(m => m.name === pathParts[0] && !m.parentId)
|
|
185
|
-
if (!currentModule) {
|
|
186
|
-
return null
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
// Traverse down the hierarchy
|
|
190
|
-
for (let i = 1; i < pathParts.length; i++) {
|
|
191
|
-
const childModule = modules.find(m => m.name === pathParts[i] && m.parentId === currentModule!.id)
|
|
192
|
-
|
|
193
|
-
if (!childModule) {
|
|
194
|
-
return null
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
currentModule = childModule
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
return currentModule.id
|
|
201
|
-
} catch (error) {
|
|
202
|
-
console.error(`Error finding module by path ${modulePath}:`, error)
|
|
203
|
-
return null
|
|
204
|
-
}
|
|
205
|
-
}
|
|
1
|
+
import prisma from '@/config/db-config'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Represents a module path structure
|
|
5
|
+
*/
|
|
6
|
+
export interface ModulePath {
|
|
7
|
+
path: string
|
|
8
|
+
name: string
|
|
9
|
+
parentPath?: string
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Creates or finds a module by its path
|
|
14
|
+
* @param modulePath - The module path (e.g., "/module1/submodule")
|
|
15
|
+
* @param moduleName - The name of the module
|
|
16
|
+
* @param parentId - Optional parent module ID
|
|
17
|
+
* @returns Promise<string> - The ID of the created or found module
|
|
18
|
+
*/
|
|
19
|
+
export async function createOrFindModule(modulePath: string, moduleName: string, parentId?: string): Promise<string> {
|
|
20
|
+
try {
|
|
21
|
+
// First, try to find existing module by name and parent
|
|
22
|
+
const existingModule = await prisma.module.findFirst({
|
|
23
|
+
where: {
|
|
24
|
+
name: moduleName,
|
|
25
|
+
parentId: parentId || null,
|
|
26
|
+
},
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
if (existingModule) {
|
|
30
|
+
return existingModule.id
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Create new module
|
|
34
|
+
const newModule = await prisma.module.create({
|
|
35
|
+
data: {
|
|
36
|
+
name: moduleName,
|
|
37
|
+
parentId: parentId || null,
|
|
38
|
+
// Add description only if it's required by the schema
|
|
39
|
+
// For now, we'll leave it empty since it's optional
|
|
40
|
+
},
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
console.log(`Created module: ${moduleName} (${modulePath})`)
|
|
44
|
+
return newModule.id
|
|
45
|
+
} catch (error) {
|
|
46
|
+
console.error(`Error creating module ${moduleName}:`, error)
|
|
47
|
+
throw error
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Builds the complete module hierarchy from a module path
|
|
53
|
+
* @param modulePath - The module path (e.g., "/module1/submodule")
|
|
54
|
+
* @returns Promise<string> - The ID of the leaf module
|
|
55
|
+
*/
|
|
56
|
+
export async function buildModuleHierarchy(modulePath: string): Promise<string> {
|
|
57
|
+
try {
|
|
58
|
+
// Parse the module path
|
|
59
|
+
const pathParts = modulePath.split('/').filter(part => part && part !== '')
|
|
60
|
+
|
|
61
|
+
// Handle empty path (root level) - create/find a default root module
|
|
62
|
+
if (pathParts.length === 0) {
|
|
63
|
+
const rootModule = await prisma.module.findFirst({
|
|
64
|
+
where: {
|
|
65
|
+
name: 'root',
|
|
66
|
+
parentId: null,
|
|
67
|
+
},
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
if (rootModule) {
|
|
71
|
+
return rootModule.id
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Create default root module
|
|
75
|
+
const newRootModule = await prisma.module.create({
|
|
76
|
+
data: {
|
|
77
|
+
name: 'root',
|
|
78
|
+
parentId: null,
|
|
79
|
+
},
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
console.log(`Created root module for features without module path`)
|
|
83
|
+
return newRootModule.id
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
let currentParentId: string | undefined
|
|
87
|
+
let currentPath = ''
|
|
88
|
+
|
|
89
|
+
// Create or find each module in the hierarchy
|
|
90
|
+
for (let i = 0; i < pathParts.length; i++) {
|
|
91
|
+
const moduleName = pathParts[i]
|
|
92
|
+
currentPath += `/${moduleName}`
|
|
93
|
+
|
|
94
|
+
const moduleId = await createOrFindModule(currentPath, moduleName, currentParentId)
|
|
95
|
+
|
|
96
|
+
currentParentId = moduleId
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return currentParentId!
|
|
100
|
+
} catch (error) {
|
|
101
|
+
console.error(`Error building module hierarchy for path ${modulePath}:`, error)
|
|
102
|
+
throw error
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Gets all existing modules as a flat list with their paths
|
|
108
|
+
* @returns Promise<Array<{id: string, name: string, path: string, parentId: string | null}>>
|
|
109
|
+
*/
|
|
110
|
+
export async function getAllModulesWithPaths(): Promise<
|
|
111
|
+
Array<{
|
|
112
|
+
id: string
|
|
113
|
+
name: string
|
|
114
|
+
path: string
|
|
115
|
+
parentId: string | null
|
|
116
|
+
}>
|
|
117
|
+
> {
|
|
118
|
+
try {
|
|
119
|
+
const modules = await prisma.module.findMany({
|
|
120
|
+
orderBy: [{ parentId: 'asc' }, { name: 'asc' }],
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
// Build paths for each module
|
|
124
|
+
const modulesWithPaths = modules.map(module => {
|
|
125
|
+
const path = buildModulePath(modules, module)
|
|
126
|
+
return {
|
|
127
|
+
id: module.id,
|
|
128
|
+
name: module.name,
|
|
129
|
+
path,
|
|
130
|
+
parentId: module.parentId,
|
|
131
|
+
}
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
return modulesWithPaths
|
|
135
|
+
} catch (error) {
|
|
136
|
+
console.error('Error fetching modules with paths:', error)
|
|
137
|
+
throw error
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Builds the full path for a module based on its hierarchy
|
|
143
|
+
* @param allModules - All modules from the database
|
|
144
|
+
* @param targetModule - The module to build the path for
|
|
145
|
+
* @returns string - The full module path
|
|
146
|
+
*/
|
|
147
|
+
function buildModulePath(
|
|
148
|
+
allModules: Array<{ id: string; name: string; parentId: string | null }>,
|
|
149
|
+
targetModule: { id: string; name: string; parentId: string | null },
|
|
150
|
+
): string {
|
|
151
|
+
const pathParts: string[] = []
|
|
152
|
+
let currentModule = targetModule
|
|
153
|
+
|
|
154
|
+
// Traverse up the hierarchy
|
|
155
|
+
while (currentModule) {
|
|
156
|
+
pathParts.unshift(currentModule.name)
|
|
157
|
+
|
|
158
|
+
if (currentModule.parentId) {
|
|
159
|
+
currentModule = allModules.find(m => m.id === currentModule.parentId)!
|
|
160
|
+
if (!currentModule) break
|
|
161
|
+
} else {
|
|
162
|
+
break
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return '/' + pathParts.join('/')
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Finds a module by its path
|
|
171
|
+
* @param modulePath - The module path to find
|
|
172
|
+
* @returns Promise<string | null> - The module ID or null if not found
|
|
173
|
+
*/
|
|
174
|
+
export async function findModuleByPath(modulePath: string): Promise<string | null> {
|
|
175
|
+
try {
|
|
176
|
+
const modules = await prisma.module.findMany()
|
|
177
|
+
const pathParts = modulePath.split('/').filter(part => part && part !== '')
|
|
178
|
+
|
|
179
|
+
if (pathParts.length === 0) {
|
|
180
|
+
return null
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Find the root module
|
|
184
|
+
let currentModule = modules.find(m => m.name === pathParts[0] && !m.parentId)
|
|
185
|
+
if (!currentModule) {
|
|
186
|
+
return null
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Traverse down the hierarchy
|
|
190
|
+
for (let i = 1; i < pathParts.length; i++) {
|
|
191
|
+
const childModule = modules.find(m => m.name === pathParts[i] && m.parentId === currentModule!.id)
|
|
192
|
+
|
|
193
|
+
if (!childModule) {
|
|
194
|
+
return null
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
currentModule = childModule
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
return currentModule.id
|
|
201
|
+
} catch (error) {
|
|
202
|
+
console.error(`Error finding module by path ${modulePath}:`, error)
|
|
203
|
+
return null
|
|
204
|
+
}
|
|
205
|
+
}
|
|
@@ -1,71 +1,71 @@
|
|
|
1
|
-
import { Module } from '@prisma/client'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Builds the hierarchical path for a module based on its parent modules
|
|
5
|
-
* @param modules - Array of all modules
|
|
6
|
-
* @param selectedModule - The module to get the path for
|
|
7
|
-
* @returns The hierarchical path as a string (e.g., "/user/user profile")
|
|
8
|
-
*/
|
|
9
|
-
export function buildModulePath(modules: Module[], selectedModule: Module): string {
|
|
10
|
-
const path: string[] = []
|
|
11
|
-
let currentModule: Module | null = selectedModule
|
|
12
|
-
|
|
13
|
-
// Build path from current module up to root
|
|
14
|
-
while (currentModule) {
|
|
15
|
-
path.unshift(currentModule.name)
|
|
16
|
-
currentModule = modules.find(m => m.id === currentModule?.parentId) || null
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
// Return path with leading slash
|
|
20
|
-
return `/${path.join('/')}`
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Alternative implementation that can handle modules with parent relationships
|
|
25
|
-
* This version works with the current data structure where we have parent info
|
|
26
|
-
*/
|
|
27
|
-
export function buildModulePathFromParent(
|
|
28
|
-
modules: (Module & { parent: { name: string } })[],
|
|
29
|
-
selectedModule: Module & { parent: { name: string } },
|
|
30
|
-
): string {
|
|
31
|
-
const path: string[] = []
|
|
32
|
-
let currentModule: (Module & { parent: { name: string } }) | null = selectedModule
|
|
33
|
-
|
|
34
|
-
// Build path from current module up to root
|
|
35
|
-
while (currentModule) {
|
|
36
|
-
path.unshift(currentModule.name)
|
|
37
|
-
|
|
38
|
-
if (currentModule.parent?.name) {
|
|
39
|
-
// Find the parent module in the modules array
|
|
40
|
-
const parentModule = modules.find(m => m.name === currentModule?.parent?.name)
|
|
41
|
-
currentModule = parentModule || null
|
|
42
|
-
} else {
|
|
43
|
-
// No parent, we've reached the root
|
|
44
|
-
currentModule = null
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// Return path with leading slash
|
|
49
|
-
return `/${path.join('/')}`
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Builds paths for all modules in a single pass for better performance
|
|
54
|
-
* @param modules - Array of all modules with parent info
|
|
55
|
-
* @returns Map of module ID to path string
|
|
56
|
-
*/
|
|
57
|
-
export function buildAllModulePaths(modules: (Module & { parent: { name: string } })[]): Map<string, string> {
|
|
58
|
-
const pathMap = new Map<string, string>()
|
|
59
|
-
|
|
60
|
-
// First pass: create a map for quick lookup
|
|
61
|
-
const moduleMap = new Map<string, Module & { parent: { name: string } }>()
|
|
62
|
-
modules.forEach(module => moduleMap.set(module.id, module))
|
|
63
|
-
|
|
64
|
-
// Second pass: build paths for each module
|
|
65
|
-
modules.forEach(module => {
|
|
66
|
-
const path = buildModulePathFromParent(modules, module)
|
|
67
|
-
pathMap.set(module.id, path)
|
|
68
|
-
})
|
|
69
|
-
|
|
70
|
-
return pathMap
|
|
71
|
-
}
|
|
1
|
+
import { Module } from '@prisma/client'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Builds the hierarchical path for a module based on its parent modules
|
|
5
|
+
* @param modules - Array of all modules
|
|
6
|
+
* @param selectedModule - The module to get the path for
|
|
7
|
+
* @returns The hierarchical path as a string (e.g., "/user/user profile")
|
|
8
|
+
*/
|
|
9
|
+
export function buildModulePath(modules: Module[], selectedModule: Module): string {
|
|
10
|
+
const path: string[] = []
|
|
11
|
+
let currentModule: Module | null = selectedModule
|
|
12
|
+
|
|
13
|
+
// Build path from current module up to root
|
|
14
|
+
while (currentModule) {
|
|
15
|
+
path.unshift(currentModule.name)
|
|
16
|
+
currentModule = modules.find(m => m.id === currentModule?.parentId) || null
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Return path with leading slash
|
|
20
|
+
return `/${path.join('/')}`
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Alternative implementation that can handle modules with parent relationships
|
|
25
|
+
* This version works with the current data structure where we have parent info
|
|
26
|
+
*/
|
|
27
|
+
export function buildModulePathFromParent(
|
|
28
|
+
modules: (Module & { parent: { name: string } })[],
|
|
29
|
+
selectedModule: Module & { parent: { name: string } },
|
|
30
|
+
): string {
|
|
31
|
+
const path: string[] = []
|
|
32
|
+
let currentModule: (Module & { parent: { name: string } }) | null = selectedModule
|
|
33
|
+
|
|
34
|
+
// Build path from current module up to root
|
|
35
|
+
while (currentModule) {
|
|
36
|
+
path.unshift(currentModule.name)
|
|
37
|
+
|
|
38
|
+
if (currentModule.parent?.name) {
|
|
39
|
+
// Find the parent module in the modules array
|
|
40
|
+
const parentModule = modules.find(m => m.name === currentModule?.parent?.name)
|
|
41
|
+
currentModule = parentModule || null
|
|
42
|
+
} else {
|
|
43
|
+
// No parent, we've reached the root
|
|
44
|
+
currentModule = null
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Return path with leading slash
|
|
49
|
+
return `/${path.join('/')}`
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Builds paths for all modules in a single pass for better performance
|
|
54
|
+
* @param modules - Array of all modules with parent info
|
|
55
|
+
* @returns Map of module ID to path string
|
|
56
|
+
*/
|
|
57
|
+
export function buildAllModulePaths(modules: (Module & { parent: { name: string } })[]): Map<string, string> {
|
|
58
|
+
const pathMap = new Map<string, string>()
|
|
59
|
+
|
|
60
|
+
// First pass: create a map for quick lookup
|
|
61
|
+
const moduleMap = new Map<string, Module & { parent: { name: string } }>()
|
|
62
|
+
modules.forEach(module => moduleMap.set(module.id, module))
|
|
63
|
+
|
|
64
|
+
// Second pass: build paths for each module
|
|
65
|
+
modules.forEach(module => {
|
|
66
|
+
const path = buildModulePathFromParent(modules, module)
|
|
67
|
+
pathMap.set(module.id, path)
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
return pathMap
|
|
71
|
+
}
|
|
@@ -7,6 +7,7 @@ export interface SpawnerOptions extends ExecaOptions {
|
|
|
7
7
|
prefixLogs?: boolean
|
|
8
8
|
logPrefix?: string
|
|
9
9
|
captureOutput?: boolean
|
|
10
|
+
retainProcessRecord?: boolean
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
export interface SpawnedProcess {
|
|
@@ -28,8 +29,29 @@ export class TaskSpawner extends EventEmitter {
|
|
|
28
29
|
private processCounter = 0
|
|
29
30
|
private outputBuffers: Map<string, { stdout: string; stderr: string }> = new Map()
|
|
30
31
|
|
|
32
|
+
private scheduleProcessCleanup(processName: string, spawnedProcess: SpawnedProcess): void {
|
|
33
|
+
setImmediate(() => {
|
|
34
|
+
spawnedProcess.output.stdout.length = 0
|
|
35
|
+
spawnedProcess.output.stderr.length = 0
|
|
36
|
+
this.outputBuffers.delete(processName)
|
|
37
|
+
this.processes.delete(processName)
|
|
38
|
+
})
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
removeProcess(processName: string): boolean {
|
|
42
|
+
this.outputBuffers.delete(processName)
|
|
43
|
+
return this.processes.delete(processName)
|
|
44
|
+
}
|
|
45
|
+
|
|
31
46
|
async spawn(command: string, args: string[] = [], options: SpawnerOptions = {}): Promise<SpawnedProcess> {
|
|
32
|
-
const {
|
|
47
|
+
const {
|
|
48
|
+
streamLogs = true,
|
|
49
|
+
prefixLogs = true,
|
|
50
|
+
logPrefix,
|
|
51
|
+
captureOutput = false,
|
|
52
|
+
retainProcessRecord = true,
|
|
53
|
+
...spawnOptions
|
|
54
|
+
} = options
|
|
33
55
|
|
|
34
56
|
const processName = logPrefix || `${command}_${++this.processCounter}`
|
|
35
57
|
const spawnedProcess: SpawnedProcess = {
|
|
@@ -49,6 +71,7 @@ export class TaskSpawner extends EventEmitter {
|
|
|
49
71
|
const stdioConfig = captureOutput ? 'pipe' : streamLogs ? 'inherit' : 'pipe'
|
|
50
72
|
const childProcess = execa(command, args, {
|
|
51
73
|
stdio: stdioConfig,
|
|
74
|
+
reject: false,
|
|
52
75
|
...spawnOptions,
|
|
53
76
|
})
|
|
54
77
|
|
|
@@ -63,6 +86,7 @@ export class TaskSpawner extends EventEmitter {
|
|
|
63
86
|
streamLogs,
|
|
64
87
|
prefixLogs,
|
|
65
88
|
captureOutput,
|
|
89
|
+
retainProcessRecord,
|
|
66
90
|
stdioConfig,
|
|
67
91
|
})
|
|
68
92
|
|
|
@@ -140,10 +164,11 @@ export class TaskSpawner extends EventEmitter {
|
|
|
140
164
|
streamLogs: boolean
|
|
141
165
|
prefixLogs: boolean
|
|
142
166
|
captureOutput: boolean
|
|
167
|
+
retainProcessRecord: boolean
|
|
143
168
|
stdioConfig: string | string[]
|
|
144
169
|
},
|
|
145
170
|
): void {
|
|
146
|
-
const { streamLogs, prefixLogs, captureOutput, stdioConfig } = options
|
|
171
|
+
const { streamLogs, prefixLogs, captureOutput, retainProcessRecord, stdioConfig } = options
|
|
147
172
|
const { process: childProcess, name } = spawnedProcess
|
|
148
173
|
|
|
149
174
|
if (stdioConfig === 'pipe') {
|
|
@@ -201,13 +226,23 @@ export class TaskSpawner extends EventEmitter {
|
|
|
201
226
|
spawnedProcess.isRunning = false
|
|
202
227
|
spawnedProcess.exitCode = code
|
|
203
228
|
spawnedProcess.endTime = new Date()
|
|
229
|
+
|
|
230
|
+
if (!retainProcessRecord) {
|
|
231
|
+
this.scheduleProcessCleanup(name, spawnedProcess)
|
|
232
|
+
}
|
|
233
|
+
|
|
204
234
|
this.emit('exit', { processName: name, code })
|
|
205
235
|
})
|
|
206
236
|
|
|
207
237
|
childProcess.on('error', (error: Error) => {
|
|
238
|
+
this.outputBuffers.delete(name)
|
|
208
239
|
spawnedProcess.isRunning = false
|
|
209
240
|
spawnedProcess.endTime = new Date()
|
|
210
241
|
|
|
242
|
+
if (!retainProcessRecord) {
|
|
243
|
+
this.scheduleProcessCleanup(name, spawnedProcess)
|
|
244
|
+
}
|
|
245
|
+
|
|
211
246
|
if (streamLogs) {
|
|
212
247
|
const prefix = prefixLogs ? `[${name}] ` : ''
|
|
213
248
|
console.error(`${prefix}ERROR: ${error.message}`)
|
|
@@ -234,3 +269,5 @@ export const spawnTask = (command: string, args: string[] = [], options: Spawner
|
|
|
234
269
|
export const killTask = (processName: string, signal?: NodeJS.Signals) => taskSpawner.killProcess(processName, signal)
|
|
235
270
|
|
|
236
271
|
export const waitForTask = (processName: string) => taskSpawner.waitForProcess(processName)
|
|
272
|
+
|
|
273
|
+
export const removeTask = (processName: string) => taskSpawner.removeProcess(processName)
|