create-appraisejs 0.2.0-alpha.6 → 0.3.0-alpha.0
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 +12 -1
- package/package.json +1 -1
- package/templates/default/.appraise-template-meta.json +2 -2
- package/templates/default/.env.example +2 -2
- package/templates/default/README.md +57 -53
- 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/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 +110 -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 +20 -16
- package/templates/default/next-env.d.ts +6 -6
- package/templates/default/next.config.ts +20 -11
- package/templates/default/package-lock.json +1775 -74
- package/templates/default/package.json +8 -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/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/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/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 -1
- package/templates/default/scripts/build-step-registry.ts +33 -0
- package/templates/default/scripts/install-playwright.ts +17 -8
- package/templates/default/scripts/install-template-step.ts +128 -0
- package/templates/default/scripts/lib/filename-utils.test.ts +24 -0
- package/templates/default/scripts/lib/filename-utils.ts +24 -0
- package/templates/default/scripts/lib/jsdoc-parser.test.ts +63 -0
- package/templates/default/scripts/lib/jsdoc-parser.ts +88 -0
- package/templates/default/scripts/lib/step-file-parser.test.ts +71 -0
- package/templates/default/scripts/lib/step-file-parser.ts +315 -0
- package/templates/default/scripts/lib/step-matcher.test.ts +86 -0
- package/templates/default/scripts/lib/step-matcher.ts +120 -0
- package/templates/default/scripts/lib/sync-script-runner.ts +23 -0
- package/templates/default/scripts/lib/sync-summary.ts +29 -0
- package/templates/default/scripts/lib/tag-parsing.test.ts +20 -0
- package/templates/default/scripts/lib/tag-parsing.ts +10 -0
- package/templates/default/scripts/lib/template-step-installer.test.ts +225 -0
- package/templates/default/scripts/lib/template-step-installer.ts +404 -0
- package/templates/default/scripts/lib/template-step-registry.test.ts +118 -0
- package/templates/default/scripts/lib/template-step-registry.ts +137 -0
- package/templates/default/scripts/protect-seeded-files.ts +51 -38
- package/templates/default/scripts/regenerate-features.ts +98 -94
- package/templates/default/scripts/run-vitest.ts +59 -0
- package/templates/default/scripts/setup-env.ts +26 -19
- package/templates/default/scripts/sync-all.ts +44 -54
- package/templates/default/scripts/sync-appraise-base-template.ts +44 -16
- package/templates/default/scripts/sync-environments.ts +22 -66
- package/templates/default/scripts/sync-locator-groups.ts +358 -410
- package/templates/default/scripts/sync-locators.ts +348 -398
- package/templates/default/scripts/sync-modules.ts +302 -341
- package/templates/default/scripts/sync-tags.ts +29 -65
- package/templates/default/scripts/sync-template-step-groups.ts +24 -182
- package/templates/default/scripts/sync-template-steps.ts +36 -493
- package/templates/default/scripts/sync-test-cases.ts +296 -539
- package/templates/default/scripts/sync-test-suites.ts +32 -79
- package/templates/default/src/actions/dashboard/dashboard-actions.ts +70 -241
- package/templates/default/src/actions/environments/environment-actions.ts +102 -188
- package/templates/default/src/actions/locator/locator-actions.ts +77 -490
- package/templates/default/src/actions/locator-groups/locator-group-actions.ts +34 -212
- package/templates/default/src/actions/locator-picker/locator-picker-actions.test.ts +81 -0
- package/templates/default/src/actions/locator-picker/locator-picker-actions.ts +20 -161
- package/templates/default/src/actions/modules/module-actions.ts +99 -135
- package/templates/default/src/actions/reports/report-actions.ts +28 -565
- package/templates/default/src/actions/settings/sync-actions.test.ts +58 -0
- package/templates/default/src/actions/tags/tag-actions.ts +99 -107
- package/templates/default/src/actions/template-step/template-step-actions.ts +33 -194
- package/templates/default/src/actions/template-step-group/template-step-group-actions.ts +35 -92
- package/templates/default/src/actions/template-test-case/template-test-case-actions.ts +98 -238
- package/templates/default/src/actions/test-case/test-case-actions.ts +108 -356
- package/templates/default/src/actions/test-run/test-run-actions.ts +74 -1081
- package/templates/default/src/actions/test-suite/test-suite-actions.ts +35 -202
- package/templates/default/src/app/(base)/environments/create/page.tsx +28 -28
- package/templates/default/src/app/(base)/environments/environment-form.test.tsx +92 -0
- package/templates/default/src/app/(base)/environments/environment-form.tsx +228 -219
- package/templates/default/src/app/(base)/environments/environment-helpers.ts +58 -0
- package/templates/default/src/app/(base)/environments/environment-table-columns.tsx +96 -96
- package/templates/default/src/app/(base)/environments/environment-table.tsx +25 -24
- package/templates/default/src/app/(base)/environments/modify/[id]/page.tsx +49 -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)/locators/create/create-locator-workspace-helpers.test.ts +71 -0
- package/templates/default/src/app/(base)/locators/create/create-locator-workspace-helpers.ts +333 -0
- package/templates/default/src/app/(base)/locators/create/create-locator-workspace.test.tsx +125 -0
- package/templates/default/src/app/(base)/locators/create/create-locator-workspace.tsx +56 -274
- package/templates/default/src/app/(base)/locators/create/page.tsx +8 -4
- package/templates/default/src/app/(base)/locators/create/use-locator-workspace.ts +183 -0
- package/templates/default/src/app/(base)/locators/locator-helpers.test.ts +28 -0
- package/templates/default/src/app/(base)/locators/locator-helpers.ts +59 -0
- package/templates/default/src/app/(base)/locators/locator-table-columns.tsx +74 -73
- package/templates/default/src/app/(base)/locators/locator-table.tsx +30 -28
- package/templates/default/src/app/(base)/locators/modify/[id]/page.tsx +20 -8
- package/templates/default/src/app/(base)/locators/page.tsx +3 -6
- package/templates/default/src/app/(base)/locators/sync-locators-button.tsx +67 -66
- package/templates/default/src/app/(base)/modules/create/page.tsx +33 -34
- package/templates/default/src/app/(base)/modules/modify/[id]/page.tsx +43 -46
- package/templates/default/src/app/(base)/modules/module-form.test.tsx +84 -0
- package/templates/default/src/app/(base)/modules/module-form.tsx +159 -126
- package/templates/default/src/app/(base)/modules/module-helpers.ts +64 -0
- package/templates/default/src/app/(base)/modules/module-table-columns.tsx +81 -85
- package/templates/default/src/app/(base)/modules/module-table.tsx +25 -24
- package/templates/default/src/app/(base)/modules/page.tsx +59 -59
- package/templates/default/src/app/(base)/reports/[id]/page.tsx +20 -260
- package/templates/default/src/app/(base)/reports/duration-chart.tsx +33 -33
- package/templates/default/src/app/(base)/reports/feature-chart.tsx +79 -78
- package/templates/default/src/app/(base)/reports/overview-chart.tsx +49 -49
- package/templates/default/src/app/(base)/reports/page.tsx +98 -98
- package/templates/default/src/app/(base)/reports/report-detail-helpers.test.ts +109 -0
- package/templates/default/src/app/(base)/reports/report-detail-helpers.ts +247 -0
- package/templates/default/src/app/(base)/reports/report-metric-card.tsx +78 -78
- 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/test-cases/page.tsx +40 -40
- 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 -58
- package/templates/default/src/app/(base)/settings/settings-sync-panel-helpers.test.tsx +40 -0
- package/templates/default/src/app/(base)/settings/settings-sync-panel-helpers.tsx +110 -0
- package/templates/default/src/app/(base)/settings/settings-sync-panel.test.tsx +127 -0
- package/templates/default/src/app/(base)/settings/settings-sync-panel.tsx +19 -134
- package/templates/default/src/app/(base)/settings/use-settings-sync.ts +66 -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-helpers.ts +13 -0
- package/templates/default/src/app/(base)/tags/tag-form.test.tsx +83 -0
- package/templates/default/src/app/(base)/tags/tag-form.tsx +143 -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 +43 -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.test.tsx +82 -0
- package/templates/default/src/app/(base)/template-step-groups/template-step-group-form.tsx +181 -167
- package/templates/default/src/app/(base)/template-step-groups/template-step-group-helpers.ts +54 -0
- 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 +34 -32
- package/templates/default/src/app/(base)/template-steps/create/page.tsx +40 -37
- package/templates/default/src/app/(base)/template-steps/modify/[id]/page.tsx +54 -49
- package/templates/default/src/app/(base)/template-steps/page.tsx +59 -58
- package/templates/default/src/app/(base)/template-steps/paramChip.tsx +233 -213
- package/templates/default/src/app/(base)/template-steps/template-step-form.test.tsx +132 -0
- package/templates/default/src/app/(base)/template-steps/template-step-form.tsx +342 -384
- package/templates/default/src/app/(base)/template-steps/template-step-helpers.test.ts +99 -0
- package/templates/default/src/app/(base)/template-steps/template-step-helpers.ts +176 -0
- package/templates/default/src/app/(base)/template-steps/template-step-table-columns.tsx +153 -158
- package/templates/default/src/app/(base)/template-steps/template-step-table.tsx +26 -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.test.tsx +109 -0
- package/templates/default/src/app/(base)/template-test-cases/template-test-case-flow.tsx +45 -84
- package/templates/default/src/app/(base)/template-test-cases/template-test-case-form.test.tsx +140 -0
- package/templates/default/src/app/(base)/template-test-cases/template-test-case-form.tsx +154 -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 +90 -76
- package/templates/default/src/app/(base)/test-cases/create-from-template/create-from-template-helpers.test.ts +94 -0
- package/templates/default/src/app/(base)/test-cases/create-from-template/create-from-template-helpers.ts +171 -0
- package/templates/default/src/app/(base)/test-cases/create-from-template/generate/[id]/page.tsx +105 -96
- package/templates/default/src/app/(base)/test-cases/create-from-template/page.tsx +40 -38
- package/templates/default/src/app/(base)/test-cases/create-from-template/template-selection-form.test.tsx +87 -0
- package/templates/default/src/app/(base)/test-cases/create-from-template/template-selection-form.tsx +83 -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 +3 -2
- package/templates/default/src/app/(base)/test-cases/test-case-flow.test.tsx +108 -0
- package/templates/default/src/app/(base)/test-cases/test-case-flow.tsx +43 -82
- package/templates/default/src/app/(base)/test-cases/test-case-form.test.tsx +202 -0
- package/templates/default/src/app/(base)/test-cases/test-case-form.tsx +263 -395
- package/templates/default/src/app/(base)/test-cases/test-case-route-helpers.test.ts +95 -0
- package/templates/default/src/app/(base)/test-cases/test-case-route-helpers.ts +147 -0
- package/templates/default/src/app/(base)/test-cases/test-case-table.tsx +4 -2
- package/templates/default/src/app/(base)/test-runs/[id]/page.tsx +11 -10
- package/templates/default/src/app/(base)/test-runs/create/page.tsx +4 -5
- package/templates/default/src/app/(base)/test-runs/page.tsx +60 -60
- package/templates/default/src/app/(base)/test-runs/test-run-form-helpers.test.ts +50 -0
- package/templates/default/src/app/(base)/test-runs/test-run-form-helpers.ts +168 -0
- package/templates/default/src/app/(base)/test-runs/test-run-form.test.tsx +138 -0
- package/templates/default/src/app/(base)/test-runs/test-run-form.tsx +111 -256
- 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-runs/use-test-run-name-validation.ts +74 -0
- package/templates/default/src/app/(base)/test-suites/create/page.tsx +17 -12
- package/templates/default/src/app/(base)/test-suites/modify/[id]/page.tsx +22 -19
- package/templates/default/src/app/(base)/test-suites/page.tsx +14 -56
- package/templates/default/src/app/(base)/test-suites/test-suite-form.test.tsx +127 -0
- package/templates/default/src/app/(base)/test-suites/test-suite-form.tsx +45 -64
- package/templates/default/src/app/(base)/test-suites/test-suite-helpers.test.ts +67 -0
- package/templates/default/src/app/(base)/test-suites/test-suite-helpers.ts +215 -0
- package/templates/default/src/app/(base)/test-suites/test-suite-table.tsx +32 -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.test.ts +83 -0
- package/templates/default/src/app/api/reports/steps/[stepId]/screenshot/route.ts +52 -52
- package/templates/default/src/app/api/test-runs/[runId]/download/route.test.ts +169 -0
- package/templates/default/src/app/api/test-runs/[runId]/download/route.ts +1 -1
- package/templates/default/src/app/api/test-runs/[runId]/trace/[testCaseId]/route.test.ts +135 -0
- package/templates/default/src/app/api/test-runs/[runId]/trace/[testCaseId]/route.ts +146 -146
- package/templates/default/src/app/globals.css +147 -147
- package/templates/default/src/app/page.tsx +1 -1
- 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-helpers.test.ts +32 -0
- package/templates/default/src/components/data-extraction/locator-inspector-helpers.ts +183 -0
- package/templates/default/src/components/data-extraction/locator-inspector.tsx +349 -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-helpers.test.ts +83 -0
- package/templates/default/src/components/diagram/dynamic-parameters-helpers.ts +158 -0
- package/templates/default/src/components/diagram/dynamic-parameters.tsx +350 -474
- package/templates/default/src/components/diagram/edit-header-option.tsx +36 -36
- package/templates/default/src/components/diagram/flow-diagram-helpers.test.ts +117 -0
- package/templates/default/src/components/diagram/flow-diagram-helpers.ts +251 -0
- package/templates/default/src/components/diagram/flow-diagram.tsx +247 -470
- package/templates/default/src/components/diagram/flow-host-helpers.test.ts +74 -0
- package/templates/default/src/components/diagram/flow-host-helpers.ts +51 -0
- package/templates/default/src/components/diagram/node-form-helpers.test.ts +92 -0
- package/templates/default/src/components/diagram/node-form-helpers.ts +100 -0
- package/templates/default/src/components/diagram/node-form.test.tsx +168 -0
- package/templates/default/src/components/diagram/node-form.tsx +199 -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/diagram/use-flow-node-order.ts +49 -0
- 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/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 +118 -116
- package/templates/default/src/components/navigation/nav-card.tsx +31 -31
- package/templates/default/src/components/navigation/nav-command-helpers.ts +122 -0
- package/templates/default/src/components/navigation/nav-command-search.tsx +125 -0
- package/templates/default/src/components/navigation/nav-command.test.tsx +106 -0
- package/templates/default/src/components/navigation/nav-command.tsx +49 -472
- 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/navigation/use-nav-command.ts +58 -0
- package/templates/default/src/components/node-header.tsx +159 -159
- package/templates/default/src/components/reports/test-case-logs-modal.tsx +310 -310
- package/templates/default/src/components/table/table-actions.tsx +174 -172
- package/templates/default/src/components/test-case/test-case-form-helpers.test.ts +100 -0
- package/templates/default/src/components/test-case/test-case-form-helpers.ts +140 -0
- package/templates/default/src/components/test-case/test-case-picker-helpers.test.ts +40 -0
- package/templates/default/src/components/test-case/test-case-picker-helpers.ts +41 -0
- package/templates/default/src/components/test-case/test-case-picker.test.tsx +44 -0
- package/templates/default/src/components/test-case/test-case-picker.tsx +16 -35
- package/templates/default/src/components/test-case/test-scenario-preview.tsx +34 -0
- package/templates/default/src/components/test-run/download-logs-button.tsx +92 -92
- package/templates/default/src/components/test-run/log-viewer-helpers.test.ts +37 -0
- package/templates/default/src/components/test-run/log-viewer-helpers.ts +80 -0
- package/templates/default/src/components/test-run/log-viewer.test.tsx +118 -0
- package/templates/default/src/components/test-run/log-viewer.tsx +51 -350
- package/templates/default/src/components/test-run/test-run-details-helpers.test.ts +31 -0
- package/templates/default/src/components/test-run/test-run-details-helpers.ts +208 -0
- package/templates/default/src/components/test-run/test-run-details.test.tsx +174 -0
- package/templates/default/src/components/test-run/test-run-details.tsx +155 -457
- package/templates/default/src/components/test-run/test-run-header-helpers.test.ts +31 -0
- package/templates/default/src/components/test-run/test-run-header-helpers.ts +23 -0
- package/templates/default/src/components/test-run/test-run-header.test.tsx +103 -0
- package/templates/default/src/components/test-run/test-run-header.tsx +27 -149
- package/templates/default/src/components/test-run/use-log-viewer.ts +213 -0
- package/templates/default/src/components/test-run/use-test-run-details.ts +184 -0
- package/templates/default/src/components/test-run/use-test-run-header.ts +89 -0
- package/templates/default/src/components/test-run/view-report-button.tsx +102 -102
- package/templates/default/src/components/test-suite/test-suite-picker-helpers.test.ts +68 -0
- package/templates/default/src/components/test-suite/test-suite-picker-helpers.ts +76 -0
- package/templates/default/src/components/test-suite/test-suite-picker.test.tsx +65 -0
- package/templates/default/src/components/test-suite/test-suite-picker.tsx +4 -72
- 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.test.tsx +122 -0
- package/templates/default/src/components/ui/data-table.tsx +298 -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.test.tsx +45 -0
- package/templates/default/src/components/ui/multi-select.tsx +158 -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.test.tsx +60 -0
- package/templates/default/src/components/user-prompt/delete-prompt.tsx +118 -87
- 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-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/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-suite-form-opts.ts +24 -24
- package/templates/default/src/hooks/use-toast.ts +187 -187
- package/templates/default/src/lib/automation/automation-path-roots.ts +95 -0
- package/templates/default/src/lib/automation/automation-workspace.ts +147 -0
- package/templates/default/src/lib/automation/paths.ts +6 -211
- package/templates/default/src/lib/bidirectional-sync.ts +432 -432
- package/templates/default/src/lib/environment-file-utils.ts +2 -1
- package/templates/default/src/lib/executor/local-executor-adapter.ts +2 -5
- package/templates/default/src/lib/feature-file-generator.ts +2 -1
- package/templates/default/src/lib/gherkin-parser.ts +0 -2
- package/templates/default/src/lib/locator-group-file-utils.ts +304 -307
- package/templates/default/src/lib/locator-picker/session-manager.ts +0 -21
- package/templates/default/src/lib/locator-picker/suggestions.ts +13 -11
- package/templates/default/src/lib/metrics/metric-calculator.ts +2 -6
- 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/sync/sync-executor.test.ts +76 -0
- package/templates/default/src/lib/sync/sync-pending-counts.test.ts +227 -226
- package/templates/default/src/lib/sync/sync-pending-counts.ts +2 -5
- 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/report-parser.ts +352 -352
- package/templates/default/src/lib/test-run/test-run-executor.ts +13 -13
- package/templates/default/src/lib/test-run/winston-logger.ts +65 -64
- 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 +2 -2
- 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/services/dashboard/dashboard-service.test.ts +106 -0
- package/templates/default/src/services/dashboard/dashboard-service.ts +173 -0
- package/templates/default/src/services/environment/environment-service.test.ts +137 -0
- package/templates/default/src/services/environment/environment-service.ts +96 -0
- package/templates/default/src/services/locator/locator-path-utils.test.ts +14 -0
- package/templates/default/src/services/locator/locator-path-utils.ts +14 -0
- package/templates/default/src/services/locator/locator-service.test.ts +63 -0
- package/templates/default/src/services/locator/locator-service.ts +479 -0
- package/templates/default/src/services/locator/locator-sync-utils.test.ts +19 -0
- package/templates/default/src/services/locator/locator-sync-utils.ts +21 -0
- package/templates/default/src/services/locator-group/locator-group-service.test.ts +123 -0
- package/templates/default/src/services/locator-group/locator-group-service.ts +180 -0
- package/templates/default/src/services/module/module-service.test.ts +89 -0
- package/templates/default/src/services/module/module-service.ts +66 -0
- package/templates/default/src/services/report/report-service.test.ts +244 -0
- package/templates/default/src/services/report/report-service.ts +438 -0
- package/templates/default/src/services/shared/constants.ts +2 -0
- package/templates/default/src/services/shared/errors.test.ts +38 -0
- package/templates/default/src/services/shared/errors.ts +44 -0
- package/templates/default/src/services/shared/index.ts +7 -0
- package/templates/default/src/services/tag/tag-service.test.ts +22 -0
- package/templates/default/src/services/tag/tag-service.ts +41 -0
- package/templates/default/src/services/template-step/template-step-service.test.ts +22 -0
- package/templates/default/src/services/template-step/template-step-service.ts +171 -0
- package/templates/default/src/services/template-step-group/template-step-group-service.test.ts +22 -0
- package/templates/default/src/services/template-step-group/template-step-group-service.ts +81 -0
- package/templates/default/src/services/template-test-case/template-test-case-service.test.ts +22 -0
- package/templates/default/src/services/template-test-case/template-test-case-service.ts +128 -0
- package/templates/default/src/services/test-case/test-case-service.test.ts +175 -0
- package/templates/default/src/services/test-case/test-case-service.ts +298 -0
- package/templates/default/src/services/test-run/test-run-helpers.ts +61 -0
- package/templates/default/src/services/test-run/test-run-service.test.ts +647 -0
- package/templates/default/src/services/test-run/test-run-service.ts +917 -0
- package/templates/default/src/services/test-suite/test-suite-service.test.ts +127 -0
- package/templates/default/src/services/test-suite/test-suite-service.ts +197 -0
- 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 +19 -6
- package/templates/default/src/types/locator/locator.type.ts +11 -11
- 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/tailwind.config.ts +62 -62
- package/templates/default/tsconfig.json +1 -1
- package/dist/cli.e2e.test.d.ts +0 -2
- package/dist/cli.e2e.test.d.ts.map +0 -1
- package/dist/cli.e2e.test.js +0 -73
- package/dist/cli.e2e.test.js.map +0 -1
- package/dist/config.test.d.ts +0 -2
- package/dist/config.test.d.ts.map +0 -1
- package/dist/config.test.js +0 -65
- package/dist/config.test.js.map +0 -1
- package/dist/copy-template.test.d.ts +0 -2
- package/dist/copy-template.test.d.ts.map +0 -1
- package/dist/copy-template.test.js +0 -71
- package/dist/copy-template.test.js.map +0 -1
- package/dist/download-repo.test.d.ts +0 -2
- package/dist/download-repo.test.d.ts.map +0 -1
- package/dist/download-repo.test.js +0 -14
- package/dist/download-repo.test.js.map +0 -1
- package/dist/install.test.d.ts +0 -2
- package/dist/install.test.d.ts.map +0 -1
- package/dist/install.test.js +0 -119
- package/dist/install.test.js.map +0 -1
- package/dist/prompts.test.d.ts +0 -2
- package/dist/prompts.test.d.ts.map +0 -1
- package/dist/prompts.test.js +0 -58
- package/dist/prompts.test.js.map +0 -1
- package/templates/default/src/actions/conflict/conflict.action.ts +0 -33
- package/templates/default/src/actions/review/review-actions.ts +0 -147
- package/templates/default/src/actions/user/user-actions.ts +0 -13
- package/templates/default/src/app/(base)/locators/locator-form.tsx +0 -163
- package/templates/default/src/app/(base)/reviews/create/page.tsx +0 -26
- package/templates/default/src/app/(base)/reviews/created-reviews-table.tsx +0 -15
- package/templates/default/src/app/(base)/reviews/modify/[id]/page.tsx +0 -26
- package/templates/default/src/app/(base)/reviews/page.tsx +0 -26
- package/templates/default/src/app/(base)/reviews/review/[id]/page.tsx +0 -26
- package/templates/default/src/app/(base)/reviews/review-form.tsx +0 -11
- package/templates/default/src/app/(base)/reviews/review-table-by-creator-columns.tsx +0 -9
- package/templates/default/src/app/(base)/reviews/review-table-by-reviewer-columns.tsx +0 -9
- package/templates/default/src/app/(base)/reviews/reviewer-reviews-table.tsx +0 -15
- package/templates/default/src/constants/form-opts/locator-form-opts.ts +0 -20
- package/templates/default/src/constants/form-opts/review-form-opts.ts +0 -23
|
@@ -18,38 +18,40 @@ export function normalizeRoute(value: string | null | undefined): string {
|
|
|
18
18
|
return '/'
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
+
const collapseSlashes = (routeValue: string) => routeValue.replace(/\/{2,}/g, '/')
|
|
22
|
+
|
|
21
23
|
try {
|
|
22
24
|
const parsed = new URL(value)
|
|
23
|
-
return parsed.pathname || '/'
|
|
25
|
+
return collapseSlashes(parsed.pathname || '/')
|
|
24
26
|
} catch {
|
|
25
27
|
const route = value.trim()
|
|
26
28
|
if (route === '') {
|
|
27
29
|
return '/'
|
|
28
30
|
}
|
|
29
31
|
|
|
30
|
-
return route.startsWith('/') ? route : `/${route}`
|
|
32
|
+
return collapseSlashes(route.startsWith('/') ? route : `/${route}`)
|
|
31
33
|
}
|
|
32
34
|
}
|
|
33
35
|
|
|
34
36
|
function buildModulePathMap(modules: Module[]): Map<string, string> {
|
|
35
|
-
const moduleById = new Map(modules.map(
|
|
37
|
+
const moduleById = new Map(modules.map(moduleRecord => [moduleRecord.id, moduleRecord]))
|
|
36
38
|
const pathByModuleId = new Map<string, string>()
|
|
37
39
|
|
|
38
|
-
const buildPath = (
|
|
39
|
-
const cached = pathByModuleId.get(
|
|
40
|
+
const buildPath = (moduleRecord: Module): string => {
|
|
41
|
+
const cached = pathByModuleId.get(moduleRecord.id)
|
|
40
42
|
if (cached) {
|
|
41
43
|
return cached
|
|
42
44
|
}
|
|
43
45
|
|
|
44
|
-
const parent =
|
|
45
|
-
const pathValue = parent ? `${buildPath(parent)}/${
|
|
46
|
+
const parent = moduleRecord.parentId ? moduleById.get(moduleRecord.parentId) : null
|
|
47
|
+
const pathValue = parent ? `${buildPath(parent)}/${moduleRecord.name}` : `/${moduleRecord.name}`
|
|
46
48
|
|
|
47
|
-
pathByModuleId.set(
|
|
48
|
-
return pathByModuleId.get(
|
|
49
|
+
pathByModuleId.set(moduleRecord.id, pathValue.replace(/\/{2,}/g, '/'))
|
|
50
|
+
return pathByModuleId.get(moduleRecord.id)!
|
|
49
51
|
}
|
|
50
52
|
|
|
51
|
-
for (const
|
|
52
|
-
buildPath(
|
|
53
|
+
for (const moduleRecord of modules) {
|
|
54
|
+
buildPath(moduleRecord)
|
|
53
55
|
}
|
|
54
56
|
|
|
55
57
|
return pathByModuleId
|
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
import prisma from '@/config/db-config'
|
|
2
|
+
import { RECENT_PERIOD_DAYS } from '@/services/shared/constants'
|
|
2
3
|
import { TestRunTestCaseResult, TestRunTestCaseStatus } from '@prisma/client'
|
|
3
4
|
|
|
4
|
-
/**
|
|
5
|
-
* Time period for "recent" runs in days
|
|
6
|
-
*/
|
|
7
|
-
const RECENT_PERIOD_DAYS = 7
|
|
8
|
-
|
|
9
5
|
/**
|
|
10
6
|
* Threshold for consecutive failures to be considered "repeatedly failing"
|
|
11
7
|
*/
|
|
@@ -38,7 +34,7 @@ export async function updateTestCaseMetrics(
|
|
|
38
34
|
): Promise<void> {
|
|
39
35
|
try {
|
|
40
36
|
// Get existing metrics or create new one
|
|
41
|
-
|
|
37
|
+
await prisma.testCaseMetrics.findUnique({
|
|
42
38
|
where: { testCaseId },
|
|
43
39
|
})
|
|
44
40
|
|
|
@@ -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
|
+
}
|