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.
Files changed (414) hide show
  1. package/README.md +52 -52
  2. package/dist/cli.e2e.test.d.ts +2 -0
  3. package/dist/cli.e2e.test.d.ts.map +1 -0
  4. package/dist/cli.e2e.test.js +73 -0
  5. package/dist/cli.e2e.test.js.map +1 -0
  6. package/dist/config.test.d.ts +2 -0
  7. package/dist/config.test.d.ts.map +1 -0
  8. package/dist/config.test.js +65 -0
  9. package/dist/config.test.js.map +1 -0
  10. package/dist/copy-template.test.d.ts +2 -0
  11. package/dist/copy-template.test.d.ts.map +1 -0
  12. package/dist/copy-template.test.js +71 -0
  13. package/dist/copy-template.test.js.map +1 -0
  14. package/dist/download-repo.test.d.ts +2 -0
  15. package/dist/download-repo.test.d.ts.map +1 -0
  16. package/dist/download-repo.test.js +14 -0
  17. package/dist/download-repo.test.js.map +1 -0
  18. package/dist/install.test.d.ts +2 -0
  19. package/dist/install.test.d.ts.map +1 -0
  20. package/dist/install.test.js +119 -0
  21. package/dist/install.test.js.map +1 -0
  22. package/dist/prepare-template-utils.d.ts.map +1 -1
  23. package/dist/prepare-template-utils.js +5 -0
  24. package/dist/prepare-template-utils.js.map +1 -1
  25. package/dist/prompts.test.d.ts +2 -0
  26. package/dist/prompts.test.d.ts.map +1 -0
  27. package/dist/prompts.test.js +58 -0
  28. package/dist/prompts.test.js.map +1 -0
  29. package/dist/scaffold-gitignore.d.ts +1 -0
  30. package/dist/scaffold-gitignore.d.ts.map +1 -1
  31. package/dist/scaffold-gitignore.js +3 -0
  32. package/dist/scaffold-gitignore.js.map +1 -1
  33. package/package.json +3 -2
  34. package/templates/default/.appraise-template-meta.json +2 -2
  35. package/templates/default/.env.example +2 -2
  36. package/templates/default/.vscode/settings.json +2 -1
  37. package/templates/default/README.md +53 -53
  38. package/templates/default/automation/mapping/locator-map.json +1 -14
  39. package/templates/default/automation/steps/actions/click.step.ts +58 -58
  40. package/templates/default/automation/steps/actions/hover.step.ts +27 -27
  41. package/templates/default/automation/steps/actions/input.step.ts +84 -84
  42. package/templates/default/automation/steps/actions/navigation.step.ts +70 -70
  43. package/templates/default/automation/steps/actions/random_data.step.ts +142 -142
  44. package/templates/default/automation/steps/actions/store.step.ts +86 -86
  45. package/templates/default/automation/steps/actions/wait.step.ts +90 -90
  46. package/templates/default/automation/steps/validations/active_state_assertion.step.ts +30 -30
  47. package/templates/default/automation/steps/validations/navigation_assertion.step.ts +22 -22
  48. package/templates/default/automation/steps/validations/text_assertion.step.ts +107 -107
  49. package/templates/default/automation/steps/validations/visibility_assertion.step.ts +26 -26
  50. package/templates/default/components.json +24 -24
  51. package/templates/default/cucumber.mjs +16 -16
  52. package/templates/default/eslint.config.mjs +16 -16
  53. package/templates/default/gitignore +3 -0
  54. package/templates/default/next-env.d.ts +6 -6
  55. package/templates/default/next.config.ts +11 -11
  56. package/templates/default/package-lock.json +146 -75
  57. package/templates/default/package.json +2 -1
  58. package/templates/default/packages/cucumber-runtime/package.json +13 -13
  59. package/templates/default/packages/cucumber-runtime/src/cache.util.ts +93 -93
  60. package/templates/default/packages/cucumber-runtime/src/cli.ts +68 -68
  61. package/templates/default/packages/cucumber-runtime/src/environment.util.ts +21 -21
  62. package/templates/default/packages/cucumber-runtime/src/executor.ts +32 -32
  63. package/templates/default/packages/cucumber-runtime/src/hooks.ts +25 -3
  64. package/templates/default/packages/cucumber-runtime/src/index.ts +17 -17
  65. package/templates/default/packages/cucumber-runtime/src/locator.util.ts +234 -234
  66. package/templates/default/packages/cucumber-runtime/src/parameter-types.ts +7 -7
  67. package/templates/default/packages/cucumber-runtime/src/paths.ts +66 -1
  68. package/templates/default/packages/cucumber-runtime/src/random-data.util.ts +35 -35
  69. package/templates/default/packages/cucumber-runtime/src/types.ts +13 -13
  70. package/templates/default/packages/cucumber-runtime/src/world.ts +44 -44
  71. package/templates/default/packages/cucumber-runtime/tsconfig.json +11 -11
  72. package/templates/default/packages/locator-picker-companion/dist/cli.d.ts +1 -0
  73. package/templates/default/packages/locator-picker-companion/dist/cli.js +302 -0
  74. package/templates/default/packages/locator-picker-companion/dist/index.d.ts +3 -0
  75. package/templates/default/packages/locator-picker-companion/dist/index.js +3 -0
  76. package/templates/default/packages/locator-picker-companion/dist/injected-picker-script.d.ts +1 -0
  77. package/templates/default/packages/locator-picker-companion/dist/injected-picker-script.js +615 -0
  78. package/templates/default/packages/locator-picker-companion/dist/launcher.d.ts +11 -0
  79. package/templates/default/packages/locator-picker-companion/dist/launcher.js +59 -0
  80. package/templates/default/packages/locator-picker-companion/dist/selector-generator.d.ts +3 -0
  81. package/templates/default/packages/locator-picker-companion/dist/selector-generator.js +257 -0
  82. package/templates/default/packages/locator-picker-companion/dist/session-file.d.ts +22 -0
  83. package/templates/default/packages/locator-picker-companion/dist/session-file.js +150 -0
  84. package/templates/default/packages/locator-picker-companion/dist/types.d.ts +31 -0
  85. package/templates/default/packages/locator-picker-companion/dist/types.js +1 -0
  86. package/templates/default/packages/locator-picker-companion/package.json +17 -0
  87. package/templates/default/packages/locator-picker-companion/src/cli.ts +428 -0
  88. package/templates/default/packages/locator-picker-companion/src/index.ts +3 -0
  89. package/templates/default/packages/locator-picker-companion/src/injected-picker-script.ts +771 -0
  90. package/templates/default/packages/locator-picker-companion/src/launcher.ts +77 -0
  91. package/templates/default/packages/locator-picker-companion/src/selector-generator.ts +339 -0
  92. package/templates/default/packages/locator-picker-companion/src/session-file.ts +226 -0
  93. package/templates/default/packages/locator-picker-companion/src/types.ts +42 -0
  94. package/templates/default/packages/locator-picker-companion/tsconfig.json +14 -0
  95. package/templates/default/postcss.config.mjs +8 -8
  96. package/templates/default/prisma/dev.db +0 -0
  97. package/templates/default/prisma/migrations/20251104113456_add_type_for_template_step_groups/migration.sql +16 -16
  98. package/templates/default/prisma/migrations/20251104170946_add_tags_to_test_suite_and_test_case/migration.sql +27 -27
  99. package/templates/default/prisma/migrations/20251112190024_add_cascade_delete_to_test_run_test_case/migration.sql +17 -17
  100. package/templates/default/prisma/migrations/20251113181100_add_test_run_log/migration.sql +12 -12
  101. package/templates/default/prisma/migrations/20251119191838_add_tag_type/migration.sql +28 -28
  102. package/templates/default/prisma/migrations/20251121164059_add_conflict_resolution/migration.sql +12 -12
  103. package/templates/default/prisma/migrations/20251223183400_add_report_model_to_db_schema/migration.sql +10 -10
  104. package/templates/default/prisma/migrations/20251223183637_add_report_test_case_entity_for_storing_test_results_for_individual_test_cases/migration.sql +10 -10
  105. package/templates/default/prisma/migrations/20251224083549_add_comprehensive_report_storage/migration.sql +108 -108
  106. package/templates/default/prisma/migrations/20251229194422_migrate_duration_to_string/migration.sql +55 -55
  107. package/templates/default/prisma/migrations/20251230124637_add_unique_constraint_to_test_run_name/migration.sql +27 -27
  108. package/templates/default/prisma/migrations/20260115094436_add_dashboard_metrics/migration.sql +59 -59
  109. package/templates/default/prisma/migrations/20260127172022_add_cascade_delete_to_step_parameters/migration.sql +34 -34
  110. package/templates/default/prisma/migrations/20260313093000_add_report_step_screenshot_path/migration.sql +1 -0
  111. package/templates/default/prisma/migrations/20260318120000_add_test_suite_context_to_test_run_test_case/migration.sql +20 -0
  112. package/templates/default/prisma/migrations/20260318173512_add_support_of_test_suite_level_runs/migration.sql +2 -0
  113. package/templates/default/prisma/schema.prisma +4 -0
  114. package/templates/default/scripts/install-playwright.ts +20 -0
  115. package/templates/default/scripts/protect-seeded-files.ts +38 -38
  116. package/templates/default/scripts/regenerate-features.ts +94 -94
  117. package/templates/default/scripts/setup-env.ts +19 -19
  118. package/templates/default/scripts/sync-all.ts +22 -66
  119. package/templates/default/scripts/sync-appraise-base-template.ts +57 -19
  120. package/templates/default/scripts/sync-environments.ts +40 -21
  121. package/templates/default/scripts/sync-locator-groups.ts +410 -410
  122. package/templates/default/scripts/sync-locators.ts +398 -398
  123. package/templates/default/scripts/sync-modules.ts +341 -341
  124. package/templates/default/scripts/sync-tags.ts +2 -3
  125. package/templates/default/scripts/sync-template-step-groups.ts +0 -3
  126. package/templates/default/scripts/sync-template-steps.ts +37 -11
  127. package/templates/default/scripts/sync-test-cases.ts +68 -16
  128. package/templates/default/scripts/sync-test-suites.ts +7 -5
  129. package/templates/default/src/actions/conflict/conflict.action.ts +33 -33
  130. package/templates/default/src/actions/dashboard/dashboard-actions.ts +240 -240
  131. package/templates/default/src/actions/environments/environment-actions.ts +188 -188
  132. package/templates/default/src/actions/locator/locator-actions.ts +490 -490
  133. package/templates/default/src/actions/locator-groups/locator-group-actions.ts +6 -3
  134. package/templates/default/src/actions/locator-picker/locator-picker-actions.ts +243 -0
  135. package/templates/default/src/actions/modules/module-actions.ts +135 -135
  136. package/templates/default/src/actions/reports/report-actions.ts +51 -49
  137. package/templates/default/src/actions/review/review-actions.ts +147 -147
  138. package/templates/default/src/actions/settings/sync-actions.ts +46 -0
  139. package/templates/default/src/actions/tags/tag-actions.ts +107 -107
  140. package/templates/default/src/actions/template-step/template-step-actions.ts +38 -4
  141. package/templates/default/src/actions/template-step-group/template-step-group-actions.ts +10 -3
  142. package/templates/default/src/actions/template-test-case/template-test-case-actions.ts +238 -238
  143. package/templates/default/src/actions/test-case/test-case-actions.ts +356 -356
  144. package/templates/default/src/actions/test-run/test-run-actions.ts +222 -129
  145. package/templates/default/src/actions/test-suite/test-suite-actions.ts +95 -17
  146. package/templates/default/src/actions/user/user-actions.ts +13 -13
  147. package/templates/default/src/app/(base)/environments/create/page.tsx +28 -28
  148. package/templates/default/src/app/(base)/environments/environment-form.tsx +219 -219
  149. package/templates/default/src/app/(base)/environments/environment-table-columns.tsx +96 -96
  150. package/templates/default/src/app/(base)/environments/environment-table.tsx +24 -24
  151. package/templates/default/src/app/(base)/environments/modify/[id]/page.tsx +46 -46
  152. package/templates/default/src/app/(base)/environments/page.tsx +59 -59
  153. package/templates/default/src/app/(base)/layout.tsx +10 -10
  154. package/templates/default/src/app/(base)/locator-groups/create/page.tsx +44 -44
  155. package/templates/default/src/app/(base)/locator-groups/locator-group-form.tsx +215 -215
  156. package/templates/default/src/app/(base)/locator-groups/locator-group-table-columns.tsx +77 -77
  157. package/templates/default/src/app/(base)/locator-groups/locator-group-table.tsx +28 -28
  158. package/templates/default/src/app/(base)/locator-groups/modify/[id]/page.tsx +46 -46
  159. package/templates/default/src/app/(base)/locator-groups/page.tsx +20 -8
  160. package/templates/default/src/app/(base)/locators/create/create-locator-workspace.tsx +542 -0
  161. package/templates/default/src/app/(base)/locators/create/page.tsx +32 -19
  162. package/templates/default/src/app/(base)/locators/locator-form.tsx +163 -163
  163. package/templates/default/src/app/(base)/locators/locator-table-columns.tsx +73 -73
  164. package/templates/default/src/app/(base)/locators/locator-table.tsx +28 -28
  165. package/templates/default/src/app/(base)/locators/modify/[id]/page.tsx +56 -27
  166. package/templates/default/src/app/(base)/locators/page.tsx +13 -13
  167. package/templates/default/src/app/(base)/locators/picker/page.tsx +7 -0
  168. package/templates/default/src/app/(base)/locators/sync-locators-button.tsx +66 -66
  169. package/templates/default/src/app/(base)/modules/create/page.tsx +34 -34
  170. package/templates/default/src/app/(base)/modules/modify/[id]/page.tsx +46 -46
  171. package/templates/default/src/app/(base)/modules/module-form.tsx +126 -126
  172. package/templates/default/src/app/(base)/modules/module-table-columns.tsx +85 -85
  173. package/templates/default/src/app/(base)/modules/module-table.tsx +24 -24
  174. package/templates/default/src/app/(base)/modules/page.tsx +59 -59
  175. package/templates/default/src/app/(base)/reports/[id]/page.tsx +40 -33
  176. package/templates/default/src/app/(base)/reports/duration-chart.tsx +33 -33
  177. package/templates/default/src/app/(base)/reports/feature-chart.tsx +78 -78
  178. package/templates/default/src/app/(base)/reports/overview-chart.tsx +49 -46
  179. package/templates/default/src/app/(base)/reports/page.tsx +98 -98
  180. package/templates/default/src/app/(base)/reports/report-metric-card.tsx +78 -16
  181. package/templates/default/src/app/(base)/reports/report-table-columns.tsx +189 -189
  182. package/templates/default/src/app/(base)/reports/report-table.tsx +72 -72
  183. package/templates/default/src/app/(base)/reports/report-view-table-columns.tsx +12 -1
  184. package/templates/default/src/app/(base)/reports/report-view-table.tsx +1 -0
  185. package/templates/default/src/app/(base)/reports/test-cases/page.tsx +40 -42
  186. package/templates/default/src/app/(base)/reports/test-cases/test-cases-metric-table-columns.tsx +115 -115
  187. package/templates/default/src/app/(base)/reports/test-cases/test-cases-metric-table.tsx +27 -27
  188. package/templates/default/src/app/(base)/reports/test-suites/page.tsx +42 -42
  189. package/templates/default/src/app/(base)/reports/test-suites/test-suites-metric-table-columns.tsx +79 -79
  190. package/templates/default/src/app/(base)/reports/test-suites/test-suites-metric-table.tsx +27 -27
  191. package/templates/default/src/app/(base)/reports/view-logs-button.tsx +58 -60
  192. package/templates/default/src/app/(base)/reviews/create/page.tsx +26 -26
  193. package/templates/default/src/app/(base)/reviews/created-reviews-table.tsx +15 -15
  194. package/templates/default/src/app/(base)/reviews/modify/[id]/page.tsx +26 -26
  195. package/templates/default/src/app/(base)/reviews/page.tsx +26 -26
  196. package/templates/default/src/app/(base)/reviews/review/[id]/page.tsx +26 -26
  197. package/templates/default/src/app/(base)/reviews/review-form.tsx +11 -11
  198. package/templates/default/src/app/(base)/reviews/review-table-by-creator-columns.tsx +9 -9
  199. package/templates/default/src/app/(base)/reviews/review-table-by-reviewer-columns.tsx +9 -9
  200. package/templates/default/src/app/(base)/reviews/reviewer-reviews-table.tsx +15 -15
  201. package/templates/default/src/app/(base)/settings/page.tsx +30 -0
  202. package/templates/default/src/app/(base)/settings/settings-sync-panel.tsx +261 -0
  203. package/templates/default/src/app/(base)/tags/create/page.tsx +39 -39
  204. package/templates/default/src/app/(base)/tags/modify/[id]/page.tsx +50 -50
  205. package/templates/default/src/app/(base)/tags/page.tsx +58 -58
  206. package/templates/default/src/app/(base)/tags/tag-form.tsx +147 -147
  207. package/templates/default/src/app/(base)/tags/tag-table-columns.tsx +63 -63
  208. package/templates/default/src/app/(base)/tags/tag-table.tsx +29 -29
  209. package/templates/default/src/app/(base)/template-step-groups/create/page.tsx +28 -28
  210. package/templates/default/src/app/(base)/template-step-groups/modify/[id]/page.tsx +45 -45
  211. package/templates/default/src/app/(base)/template-step-groups/page.tsx +60 -60
  212. package/templates/default/src/app/(base)/template-step-groups/template-step-group-form.tsx +167 -167
  213. package/templates/default/src/app/(base)/template-step-groups/template-step-group-table-columns.tsx +89 -89
  214. package/templates/default/src/app/(base)/template-step-groups/template-step-group-table.tsx +32 -32
  215. package/templates/default/src/app/(base)/template-steps/create/page.tsx +37 -37
  216. package/templates/default/src/app/(base)/template-steps/modify/[id]/page.tsx +49 -49
  217. package/templates/default/src/app/(base)/template-steps/page.tsx +58 -58
  218. package/templates/default/src/app/(base)/template-steps/paramChip.tsx +213 -213
  219. package/templates/default/src/app/(base)/template-steps/template-step-form.tsx +384 -384
  220. package/templates/default/src/app/(base)/template-steps/template-step-table-columns.tsx +158 -158
  221. package/templates/default/src/app/(base)/template-steps/template-step-table.tsx +24 -24
  222. package/templates/default/src/app/(base)/template-test-cases/create/page.tsx +56 -56
  223. package/templates/default/src/app/(base)/template-test-cases/modify/[id]/page.tsx +89 -89
  224. package/templates/default/src/app/(base)/template-test-cases/page.tsx +58 -58
  225. package/templates/default/src/app/(base)/template-test-cases/template-test-case-flow.tsx +84 -84
  226. package/templates/default/src/app/(base)/template-test-cases/template-test-case-form.tsx +262 -262
  227. package/templates/default/src/app/(base)/template-test-cases/template-test-case-table-columns.tsx +76 -76
  228. package/templates/default/src/app/(base)/template-test-cases/template-test-case-table.tsx +32 -32
  229. package/templates/default/src/app/(base)/test-cases/create/page.tsx +76 -76
  230. package/templates/default/src/app/(base)/test-cases/create-from-template/generate/[id]/page.tsx +96 -96
  231. package/templates/default/src/app/(base)/test-cases/create-from-template/page.tsx +38 -38
  232. package/templates/default/src/app/(base)/test-cases/create-from-template/template-selection-form.tsx +73 -73
  233. package/templates/default/src/app/(base)/test-cases/modify/[id]/page.tsx +106 -106
  234. package/templates/default/src/app/(base)/test-cases/page.tsx +2 -2
  235. package/templates/default/src/app/(base)/test-cases/test-case-flow.tsx +82 -82
  236. package/templates/default/src/app/(base)/test-cases/test-case-form.tsx +395 -395
  237. package/templates/default/src/app/(base)/test-cases/test-case-table-columns.tsx +6 -71
  238. package/templates/default/src/app/(base)/test-cases/test-case-table.tsx +2 -2
  239. package/templates/default/src/app/(base)/test-runs/[id]/page.tsx +4 -1
  240. package/templates/default/src/app/(base)/test-runs/create/page.tsx +11 -9
  241. package/templates/default/src/app/(base)/test-runs/page.tsx +60 -60
  242. package/templates/default/src/app/(base)/test-runs/test-run-form.tsx +37 -44
  243. package/templates/default/src/app/(base)/test-runs/test-run-table-columns.tsx +229 -229
  244. package/templates/default/src/app/(base)/test-runs/test-run-table.tsx +127 -127
  245. package/templates/default/src/app/(base)/test-suites/create/page.tsx +3 -2
  246. package/templates/default/src/app/(base)/test-suites/modify/[id]/page.tsx +2 -1
  247. package/templates/default/src/app/(base)/test-suites/page.tsx +57 -21
  248. package/templates/default/src/app/(base)/test-suites/test-suite-form.tsx +16 -17
  249. package/templates/default/src/app/(base)/test-suites/test-suite-table-columns.tsx +2 -1
  250. package/templates/default/src/app/(base)/test-suites/test-suite-table.tsx +29 -29
  251. package/templates/default/src/app/(dashboard-components)/app-drawer.tsx +187 -187
  252. package/templates/default/src/app/(dashboard-components)/data-card-grid.tsx +12 -12
  253. package/templates/default/src/app/(dashboard-components)/data-card.tsx +26 -26
  254. package/templates/default/src/app/(dashboard-components)/execution-health-panel.tsx +56 -56
  255. package/templates/default/src/app/(dashboard-components)/ongoing-test-runs-card.tsx +87 -87
  256. package/templates/default/src/app/(dashboard-components)/quick-actions-drawer.tsx +44 -44
  257. package/templates/default/src/app/api/reports/steps/[stepId]/screenshot/route.ts +52 -0
  258. package/templates/default/src/app/api/test-runs/[runId]/download/route.ts +97 -34
  259. package/templates/default/src/app/api/test-runs/[runId]/logs/route.ts +4 -1
  260. package/templates/default/src/app/api/test-runs/[runId]/trace/[testCaseId]/route.ts +146 -147
  261. package/templates/default/src/app/globals.css +147 -147
  262. package/templates/default/src/app/layout.tsx +4 -0
  263. package/templates/default/src/app/page.tsx +2 -0
  264. package/templates/default/src/assets/icons/empty-tube.tsx +23 -23
  265. package/templates/default/src/assets/icons/tube-plus.tsx +29 -29
  266. package/templates/default/src/components/base-node.tsx +21 -21
  267. package/templates/default/src/components/chart/pie-chart.tsx +73 -73
  268. package/templates/default/src/components/data-extraction/locator-inspector.tsx +460 -460
  269. package/templates/default/src/components/data-state/empty-state.tsx +40 -40
  270. package/templates/default/src/components/data-visualization/info-card.tsx +70 -70
  271. package/templates/default/src/components/data-visualization/info-grid.tsx +22 -22
  272. package/templates/default/src/components/diagram/button-edge.tsx +54 -54
  273. package/templates/default/src/components/diagram/dynamic-parameters.tsx +474 -474
  274. package/templates/default/src/components/diagram/edit-header-option.tsx +36 -36
  275. package/templates/default/src/components/diagram/flow-diagram.tsx +470 -470
  276. package/templates/default/src/components/diagram/node-form.tsx +262 -262
  277. package/templates/default/src/components/diagram/options-header-node.tsx +57 -57
  278. package/templates/default/src/components/diagram/template-step-combobox.tsx +155 -155
  279. package/templates/default/src/components/form/error-message.tsx +7 -7
  280. package/templates/default/src/components/kokonutui/smooth-tab.tsx +453 -453
  281. package/templates/default/src/components/loading-skeleton/data-table/data-table-skeleton.tsx +30 -30
  282. package/templates/default/src/components/loading-skeleton/form/button-skeleton.tsx +8 -8
  283. package/templates/default/src/components/loading-skeleton/form/icon-button-skeleton.tsx +8 -8
  284. package/templates/default/src/components/loading-skeleton/form/text-input-skeleton.tsx +8 -8
  285. package/templates/default/src/components/loading-skeleton/visualization/table-skeleton.tsx +14 -14
  286. package/templates/default/src/components/logo.tsx +15 -15
  287. package/templates/default/src/components/navigation/command-badge.tsx +34 -34
  288. package/templates/default/src/components/navigation/command-chain-input.tsx +51 -51
  289. package/templates/default/src/components/navigation/entity-search-command.tsx +116 -116
  290. package/templates/default/src/components/navigation/nav-card.tsx +31 -31
  291. package/templates/default/src/components/navigation/nav-command.tsx +13 -0
  292. package/templates/default/src/components/navigation/nav-link.tsx +60 -60
  293. package/templates/default/src/components/navigation/nav-menu-card-deck.tsx +112 -112
  294. package/templates/default/src/components/node-header.tsx +159 -159
  295. package/templates/default/src/components/reports/test-case-logs-modal.tsx +310 -253
  296. package/templates/default/src/components/table/table-actions.tsx +172 -172
  297. package/templates/default/src/components/test-case/test-case-columns.tsx +76 -0
  298. package/templates/default/src/components/test-case/test-case-picker.tsx +244 -0
  299. package/templates/default/src/components/test-run/download-logs-button.tsx +92 -99
  300. package/templates/default/src/components/test-run/log-viewer.tsx +1 -14
  301. package/templates/default/src/components/test-run/test-run-details.tsx +15 -2
  302. package/templates/default/src/components/test-run/test-run-header.tsx +149 -149
  303. package/templates/default/src/components/test-run/view-report-button.tsx +102 -102
  304. package/templates/default/src/components/test-suite/test-suite-picker.tsx +444 -0
  305. package/templates/default/src/components/theme/mode-toggle.tsx +54 -54
  306. package/templates/default/src/components/theme/theme-provider.tsx +8 -8
  307. package/templates/default/src/components/typography/page-header-subtitle.tsx +7 -7
  308. package/templates/default/src/components/typography/page-header.tsx +7 -7
  309. package/templates/default/src/components/ui/alert-dialog.tsx +106 -106
  310. package/templates/default/src/components/ui/alert.tsx +43 -43
  311. package/templates/default/src/components/ui/avatar.tsx +40 -40
  312. package/templates/default/src/components/ui/badge.tsx +29 -29
  313. package/templates/default/src/components/ui/button.tsx +47 -47
  314. package/templates/default/src/components/ui/calendar.tsx +158 -158
  315. package/templates/default/src/components/ui/card.tsx +43 -43
  316. package/templates/default/src/components/ui/checkbox.tsx +28 -28
  317. package/templates/default/src/components/ui/command.tsx +135 -135
  318. package/templates/default/src/components/ui/data-table-column-header.tsx +61 -61
  319. package/templates/default/src/components/ui/data-table-pagination.tsx +87 -87
  320. package/templates/default/src/components/ui/data-table-view-options.tsx +50 -50
  321. package/templates/default/src/components/ui/data-table.tsx +261 -261
  322. package/templates/default/src/components/ui/dialog.tsx +97 -97
  323. package/templates/default/src/components/ui/dropdown-menu.tsx +182 -182
  324. package/templates/default/src/components/ui/input.tsx +22 -22
  325. package/templates/default/src/components/ui/kbd.tsx +28 -28
  326. package/templates/default/src/components/ui/label.tsx +19 -19
  327. package/templates/default/src/components/ui/loading.tsx +12 -12
  328. package/templates/default/src/components/ui/multi-select-with-preview.tsx +116 -116
  329. package/templates/default/src/components/ui/multi-select.tsx +142 -142
  330. package/templates/default/src/components/ui/navigation-menu.tsx +120 -120
  331. package/templates/default/src/components/ui/popover.tsx +33 -33
  332. package/templates/default/src/components/ui/progress.tsx +25 -25
  333. package/templates/default/src/components/ui/radio-group.tsx +44 -44
  334. package/templates/default/src/components/ui/scroll-area.tsx +40 -40
  335. package/templates/default/src/components/ui/select.tsx +151 -151
  336. package/templates/default/src/components/ui/separator.tsx +22 -22
  337. package/templates/default/src/components/ui/skeleton.tsx +7 -7
  338. package/templates/default/src/components/ui/table.tsx +76 -76
  339. package/templates/default/src/components/ui/tabs.tsx +55 -55
  340. package/templates/default/src/components/ui/textarea.tsx +21 -21
  341. package/templates/default/src/components/ui/toast.tsx +113 -113
  342. package/templates/default/src/components/ui/toaster.tsx +26 -26
  343. package/templates/default/src/components/user-prompt/delete-prompt.tsx +87 -87
  344. package/templates/default/src/config/db-config.ts +10 -10
  345. package/templates/default/src/constants/form-opts/diagram/node-form.ts +30 -30
  346. package/templates/default/src/constants/form-opts/environment-form-opts.ts +24 -24
  347. package/templates/default/src/constants/form-opts/locator-form-opts.ts +20 -20
  348. package/templates/default/src/constants/form-opts/locator-group-form-opts.ts +28 -28
  349. package/templates/default/src/constants/form-opts/module-form-opts.ts +21 -21
  350. package/templates/default/src/constants/form-opts/review-form-opts.ts +23 -23
  351. package/templates/default/src/constants/form-opts/tag-form-opts.ts +42 -42
  352. package/templates/default/src/constants/form-opts/template-selection-form-opts.ts +16 -16
  353. package/templates/default/src/constants/form-opts/template-step-group-form-opts.ts +24 -24
  354. package/templates/default/src/constants/form-opts/template-test-case-form-opts.ts +39 -39
  355. package/templates/default/src/constants/form-opts/template-test-step-form-opts.ts +36 -36
  356. package/templates/default/src/constants/form-opts/test-case-form-opts.ts +43 -43
  357. package/templates/default/src/constants/form-opts/test-run-form-opts.ts +5 -3
  358. package/templates/default/src/constants/form-opts/test-suite-form-opts.ts +24 -24
  359. package/templates/default/src/hooks/use-toast.ts +187 -187
  360. package/templates/default/src/lib/automation/paths.ts +42 -12
  361. package/templates/default/src/lib/automation/projection-service.ts +2 -1
  362. package/templates/default/src/lib/bidirectional-sync.ts +432 -432
  363. package/templates/default/src/lib/database-sync.ts +2 -7
  364. package/templates/default/src/lib/environment-file-utils.ts +184 -184
  365. package/templates/default/src/lib/executor/local-executor-adapter.ts +24 -25
  366. package/templates/default/src/lib/executor/types.ts +2 -2
  367. package/templates/default/src/lib/feature-file-generator.ts +5 -66
  368. package/templates/default/src/lib/gherkin-parser.ts +259 -259
  369. package/templates/default/src/lib/locator-group-file-utils.ts +307 -307
  370. package/templates/default/src/lib/locator-picker/session-manager.ts +452 -0
  371. package/templates/default/src/lib/locator-picker/suggestions.ts +124 -0
  372. package/templates/default/src/lib/metrics/metric-calculator.ts +5 -0
  373. package/templates/default/src/lib/module-hierarchy-builder.ts +205 -205
  374. package/templates/default/src/lib/path-helpers/module-path.ts +71 -71
  375. package/templates/default/src/lib/process/task-spawner.ts +39 -2
  376. package/templates/default/src/lib/sync/projected-feature-utils.ts +113 -0
  377. package/templates/default/src/lib/sync/sync-executor.ts +130 -0
  378. package/templates/default/src/lib/sync/sync-pending-counts.test.ts +239 -0
  379. package/templates/default/src/lib/sync/sync-pending-counts.ts +1358 -0
  380. package/templates/default/src/lib/sync/sync-registry.ts +149 -0
  381. package/templates/default/src/lib/tag-utils.ts +28 -0
  382. package/templates/default/src/lib/template-sync-utils.d.ts +6 -6
  383. package/templates/default/src/lib/template-sync-utils.js +46 -46
  384. package/templates/default/src/lib/template-sync-utils.ts +63 -63
  385. package/templates/default/src/lib/test-case-utils.ts +6 -6
  386. package/templates/default/src/lib/test-run/log-formatter.ts +83 -83
  387. package/templates/default/src/lib/test-run/matching.ts +117 -0
  388. package/templates/default/src/lib/test-run/process-manager.ts +2 -0
  389. package/templates/default/src/lib/test-run/report-parser.ts +352 -316
  390. package/templates/default/src/lib/test-run/test-run-executor.ts +13 -15
  391. package/templates/default/src/lib/test-run/winston-logger.ts +64 -66
  392. package/templates/default/src/lib/test-suite-identifier-service.ts +76 -0
  393. package/templates/default/src/lib/test-suite-utils.ts +6 -0
  394. package/templates/default/src/lib/transformers/gherkin-converter.ts +42 -42
  395. package/templates/default/src/lib/transformers/key-to-icon-transformer.tsx +95 -95
  396. package/templates/default/src/lib/transformers/template-test-case-converter.ts +160 -160
  397. package/templates/default/src/lib/utils/node-param-validation.ts +81 -81
  398. package/templates/default/src/lib/utils/template-step-file-generator.ts +104 -104
  399. package/templates/default/src/lib/utils/template-step-file-manager-intelligent.ts +0 -8
  400. package/templates/default/src/lib/utils/template-step-file-manager.ts +166 -166
  401. package/templates/default/src/lib/utils.ts +31 -31
  402. package/templates/default/src/types/diagram/diagram.ts +34 -34
  403. package/templates/default/src/types/diagram/template-step.ts +11 -11
  404. package/templates/default/src/types/executor/browser.type.ts +1 -1
  405. package/templates/default/src/types/form/actionHandler.ts +6 -6
  406. package/templates/default/src/types/locator/locator.type.ts +11 -11
  407. package/templates/default/src/types/locator-picker.ts +65 -0
  408. package/templates/default/src/types/step/step.type.ts +1 -1
  409. package/templates/default/src/types/table/data-table.ts +6 -6
  410. package/templates/default/src/types/test-case-picker.ts +6 -0
  411. package/templates/default/src/types/test-suite-picker.ts +18 -0
  412. package/templates/default/tailwind.config.ts +62 -62
  413. package/templates/default/tsconfig.json +4 -1
  414. package/templates/default/appraisejs.config.json +0 -1
@@ -1,104 +1,104 @@
1
- import { promises as fs } from 'fs'
2
- import { join } from 'path'
3
- import prettier from 'prettier'
4
- import { TemplateStep, TemplateStepGroupType } from '@prisma/client'
5
- import {
6
- ensureAutomationWorkspaceReady,
7
- getAutomationActionStepsDir,
8
- getAutomationStepsDir,
9
- getAutomationValidationStepsDir,
10
- } from '@/lib/automation/paths'
11
-
12
- const RUNTIME_IMPORT = '../../../packages/cucumber-runtime/src/index.js'
13
- const REQUIRED_RUNTIME_IMPORT =
14
- `import { When, Then, CustomWorld, expect, SelectorName, resolveLocator, getEnvironment, generateRandomData, RandomDataType } from '${RUNTIME_IMPORT}';\n\n`
15
-
16
- export function sanitizeFileName(groupName: string): string {
17
- return groupName
18
- .toLowerCase()
19
- .trim()
20
- .replace(/\s+/g, '_')
21
- .replace(/[^a-z0-9_]/g, '')
22
- }
23
-
24
- export function generateFileContent(templateSteps: TemplateStep[]): string {
25
- if (!templateSteps || templateSteps.length === 0) {
26
- return REQUIRED_RUNTIME_IMPORT + '// This file is generated automatically. Add template steps to this group to generate content.'
27
- }
28
-
29
- const functionDefinitions = templateSteps
30
- .map(step => step.functionDefinition)
31
- .filter(Boolean)
32
- .join('\n\n')
33
-
34
- return REQUIRED_RUNTIME_IMPORT + functionDefinitions
35
- }
36
-
37
- export async function formatFileContent(content: string): Promise<string> {
38
- try {
39
- return await prettier.format(content, {
40
- parser: 'typescript',
41
- semi: true,
42
- singleQuote: true,
43
- trailingComma: 'es5',
44
- printWidth: 80,
45
- tabWidth: 2,
46
- })
47
- } catch (error) {
48
- console.error('Prettier formatting failed:', error)
49
- return content
50
- }
51
- }
52
-
53
- export function getSubdirectoryName(type: TemplateStepGroupType | string): string {
54
- const typeStr = String(type)
55
- return typeStr === 'ACTION' ? 'actions' : 'validations'
56
- }
57
-
58
- export async function ensureStepsDirectory(): Promise<string> {
59
- await ensureAutomationWorkspaceReady()
60
- const stepsDir = getAutomationStepsDir()
61
- await fs.mkdir(stepsDir, { recursive: true })
62
- await fs.mkdir(getAutomationActionStepsDir(), { recursive: true })
63
- await fs.mkdir(getAutomationValidationStepsDir(), { recursive: true })
64
- return stepsDir
65
- }
66
-
67
- export function getFilePath(groupName: string, type: TemplateStepGroupType | string): string {
68
- const sanitizedName = sanitizeFileName(groupName)
69
- const subdirectory = getSubdirectoryName(type)
70
- return join(process.cwd(), 'automation', 'steps', subdirectory, `${sanitizedName}.step.ts`)
71
- }
72
-
73
- export async function writeTemplateStepFile(
74
- groupName: string,
75
- content: string,
76
- type: TemplateStepGroupType | string,
77
- ): Promise<void> {
78
- try {
79
- await ensureStepsDirectory()
80
- const formattedContent = await formatFileContent(content)
81
- const filePath = getFilePath(groupName, type)
82
- await fs.writeFile(filePath, formattedContent, 'utf8')
83
- } catch (error) {
84
- console.error(`Failed to write template step file for group "${groupName}":`, error)
85
- throw new Error(`File generation failed: ${error}`)
86
- }
87
- }
88
-
89
- export async function deleteTemplateStepFile(groupName: string, type: TemplateStepGroupType | string): Promise<void> {
90
- try {
91
- const filePath = getFilePath(groupName, type)
92
-
93
- try {
94
- await fs.access(filePath)
95
- } catch {
96
- return
97
- }
98
-
99
- await fs.unlink(filePath)
100
- } catch (error) {
101
- console.error(`Failed to delete template step file for group "${groupName}":`, error)
102
- throw new Error(`File deletion failed: ${error}`)
103
- }
104
- }
1
+ import { promises as fs } from 'fs'
2
+ import { join } from 'path'
3
+ import prettier from 'prettier'
4
+ import { TemplateStep, TemplateStepGroupType } from '@prisma/client'
5
+ import {
6
+ ensureAutomationWorkspaceReady,
7
+ getAutomationActionStepsDir,
8
+ getAutomationStepsDir,
9
+ getAutomationValidationStepsDir,
10
+ } from '@/lib/automation/paths'
11
+
12
+ const RUNTIME_IMPORT = '../../../packages/cucumber-runtime/src/index.js'
13
+ const REQUIRED_RUNTIME_IMPORT =
14
+ `import { When, Then, CustomWorld, expect, SelectorName, resolveLocator, getEnvironment, generateRandomData, RandomDataType } from '${RUNTIME_IMPORT}';\n\n`
15
+
16
+ export function sanitizeFileName(groupName: string): string {
17
+ return groupName
18
+ .toLowerCase()
19
+ .trim()
20
+ .replace(/\s+/g, '_')
21
+ .replace(/[^a-z0-9_]/g, '')
22
+ }
23
+
24
+ export function generateFileContent(templateSteps: TemplateStep[]): string {
25
+ if (!templateSteps || templateSteps.length === 0) {
26
+ return REQUIRED_RUNTIME_IMPORT + '// This file is generated automatically. Add template steps to this group to generate content.'
27
+ }
28
+
29
+ const functionDefinitions = templateSteps
30
+ .map(step => step.functionDefinition)
31
+ .filter(Boolean)
32
+ .join('\n\n')
33
+
34
+ return REQUIRED_RUNTIME_IMPORT + functionDefinitions
35
+ }
36
+
37
+ export async function formatFileContent(content: string): Promise<string> {
38
+ try {
39
+ return await prettier.format(content, {
40
+ parser: 'typescript',
41
+ semi: true,
42
+ singleQuote: true,
43
+ trailingComma: 'es5',
44
+ printWidth: 80,
45
+ tabWidth: 2,
46
+ })
47
+ } catch (error) {
48
+ console.error('Prettier formatting failed:', error)
49
+ return content
50
+ }
51
+ }
52
+
53
+ export function getSubdirectoryName(type: TemplateStepGroupType | string): string {
54
+ const typeStr = String(type)
55
+ return typeStr === 'ACTION' ? 'actions' : 'validations'
56
+ }
57
+
58
+ export async function ensureStepsDirectory(): Promise<string> {
59
+ await ensureAutomationWorkspaceReady()
60
+ const stepsDir = getAutomationStepsDir()
61
+ await fs.mkdir(stepsDir, { recursive: true })
62
+ await fs.mkdir(getAutomationActionStepsDir(), { recursive: true })
63
+ await fs.mkdir(getAutomationValidationStepsDir(), { recursive: true })
64
+ return stepsDir
65
+ }
66
+
67
+ export function getFilePath(groupName: string, type: TemplateStepGroupType | string): string {
68
+ const sanitizedName = sanitizeFileName(groupName)
69
+ const subdirectory = getSubdirectoryName(type)
70
+ return join(process.cwd(), 'automation', 'steps', subdirectory, `${sanitizedName}.step.ts`)
71
+ }
72
+
73
+ export async function writeTemplateStepFile(
74
+ groupName: string,
75
+ content: string,
76
+ type: TemplateStepGroupType | string,
77
+ ): Promise<void> {
78
+ try {
79
+ await ensureStepsDirectory()
80
+ const formattedContent = await formatFileContent(content)
81
+ const filePath = getFilePath(groupName, type)
82
+ await fs.writeFile(filePath, formattedContent, 'utf8')
83
+ } catch (error) {
84
+ console.error(`Failed to write template step file for group "${groupName}":`, error)
85
+ throw new Error(`File generation failed: ${error}`)
86
+ }
87
+ }
88
+
89
+ export async function deleteTemplateStepFile(groupName: string, type: TemplateStepGroupType | string): Promise<void> {
90
+ try {
91
+ const filePath = getFilePath(groupName, type)
92
+
93
+ try {
94
+ await fs.access(filePath)
95
+ } catch {
96
+ return
97
+ }
98
+
99
+ await fs.unlink(filePath)
100
+ } catch (error) {
101
+ console.error(`Failed to delete template step file for group "${groupName}":`, error)
102
+ throw new Error(`File deletion failed: ${error}`)
103
+ }
104
+ }
@@ -28,7 +28,6 @@ function generateGroupJSDocComment(
28
28
  function extractGroupJSDocBounds(content: string): { startLine: number; endLine: number } | null {
29
29
  const lines = content.split('\n')
30
30
 
31
- // Look for JSDoc comment at the very top of the file
32
31
  if (lines.length === 0) {
33
32
  return null
34
33
  }
@@ -38,25 +37,20 @@ function extractGroupJSDocBounds(content: string): { startLine: number; endLine:
38
37
  return null
39
38
  }
40
39
 
41
- // Check if this JSDoc contains group metadata (@type distinguishes group from step JSDoc)
42
40
  let hasType = false
43
41
  let endLine = -1
44
42
 
45
- // Look through the JSDoc block (should end within first few lines)
46
43
  for (let i = 0; i < lines.length && i < 10; i++) {
47
44
  const line = lines[i].trim()
48
45
 
49
46
  if (line === '*/') {
50
- // Found end of JSDoc
51
47
  endLine = i
52
48
  break
53
49
  } else if (line.startsWith('* @type') || line.startsWith('*@type')) {
54
- // Found @type - this is group metadata (steps have @icon, not @type)
55
50
  hasType = true
56
51
  }
57
52
  }
58
53
 
59
- // If we found a JSDoc block at the top with @type, return its bounds
60
54
  if (hasType && endLine >= 0) {
61
55
  return { startLine: 0, endLine }
62
56
  }
@@ -704,5 +698,3 @@ export async function renameTemplateStepGroupFile(
704
698
  }
705
699
  }
706
700
 
707
-
708
-
@@ -1,166 +1,166 @@
1
- import prisma from '@/config/db-config'
2
- import { writeTemplateStepFile, deleteTemplateStepFile, generateFileContent } from './template-step-file-generator'
3
- import { TemplateStepGroupType } from '@prisma/client'
4
-
5
- // TemplateStepGroupType helper - will be available from @prisma/client after migration
6
- type TemplateStepGroupTypeLocal = 'ACTION' | 'VALIDATION'
7
-
8
- // Type helper to safely extract type from Prisma templateStepGroup records
9
- type TemplateStepGroupWithType = {
10
- id: string
11
- name: string
12
- description: string | null
13
- type?: TemplateStepGroupTypeLocal
14
- createdAt: Date
15
- updatedAt: Date
16
- }
17
-
18
- function getGroupType(group: unknown): TemplateStepGroupTypeLocal {
19
- const groupWithType = group as TemplateStepGroupWithType
20
- const type = groupWithType.type
21
- if (type === 'VALIDATION' || type === 'ACTION') {
22
- return type
23
- }
24
- return 'ACTION' // default
25
- }
26
-
27
- /**
28
- * Regenerates the file for a specific template step group
29
- * This function is called whenever template steps in a group change
30
- */
31
- export async function regenerateTemplateStepGroupFile(groupId: string): Promise<void> {
32
- try {
33
- // Get the template step group with all its template steps
34
- const group = await prisma.templateStepGroup.findUnique({
35
- where: { id: groupId },
36
- include: {
37
- templateSteps: {
38
- orderBy: {
39
- // Order by creation time or any other field you prefer
40
- createdAt: 'asc',
41
- },
42
- },
43
- },
44
- })
45
-
46
- if (!group) {
47
- throw new Error(`Template step group with ID ${groupId} not found`)
48
- }
49
-
50
- // Generate file content from template steps
51
- const content = generateFileContent(group.templateSteps)
52
-
53
- // Write the file
54
- const type = getGroupType(group)
55
- await writeTemplateStepFile(group.name, content, type)
56
-
57
- console.log(`File regenerated for template step group: ${group.name}`)
58
- } catch (error) {
59
- console.error(`Failed to regenerate file for template step group ${groupId}:`, error)
60
- throw new Error(`File regeneration failed: ${error}`)
61
- }
62
- }
63
-
64
- /**
65
- * Creates a placeholder file for a new template step group
66
- * Called when a new group is created
67
- * @deprecated Use createTemplateStepGroupFile from template-step-file-manager-intelligent.ts instead
68
- */
69
- export async function createTemplateStepGroupFile(
70
- groupName: string,
71
- type: TemplateStepGroupType | string = 'ACTION',
72
- ): Promise<void> {
73
- try {
74
- // Create empty placeholder content with required imports
75
- const placeholderContent =
76
- '// This file is generated automatically. Add template steps to this group to generate content.'
77
-
78
- // Write the placeholder file
79
- await writeTemplateStepFile(groupName, placeholderContent, type)
80
-
81
- console.log(`Placeholder file created for template step group: ${groupName}`)
82
- } catch (error) {
83
- console.error(`Failed to create placeholder file for group "${groupName}":`, error)
84
- throw new Error(`File creation failed: ${error}`)
85
- }
86
- }
87
-
88
- /**
89
- * Deletes the file for a template step group
90
- * Called when a group is deleted
91
- * @deprecated Use removeTemplateStepGroupFile from template-step-file-manager-intelligent.ts instead
92
- */
93
- export async function removeTemplateStepGroupFile(
94
- groupName: string,
95
- type: TemplateStepGroupType | string = 'ACTION',
96
- ): Promise<void> {
97
- try {
98
- await deleteTemplateStepFile(groupName, type)
99
-
100
- console.log(`File deleted for template step group: ${groupName}`)
101
- } catch (error) {
102
- console.error(`Failed to delete file for group "${groupName}":`, error)
103
- throw new Error(`File deletion failed: ${error}`)
104
- }
105
- }
106
-
107
- /**
108
- * Handles file regeneration when a template step is created, updated, or deleted
109
- * This function determines which groups need file regeneration
110
- */
111
- export async function handleTemplateStepChange(
112
- templateStepId: string,
113
- operation: 'create' | 'update' | 'delete',
114
- ): Promise<void> {
115
- try {
116
- let groupId: string | null = null
117
-
118
- if (operation === 'delete') {
119
- // For delete operations, we need to get the group ID before deletion
120
- const step = await prisma.templateStep.findUnique({
121
- where: { id: templateStepId },
122
- select: { templateStepGroupId: true },
123
- })
124
- groupId = step?.templateStepGroupId || null
125
- } else {
126
- // For create/update operations, get the current group ID
127
- const step = await prisma.templateStep.findUnique({
128
- where: { id: templateStepId },
129
- select: { templateStepGroupId: true },
130
- })
131
- groupId = step?.templateStepGroupId || null
132
- }
133
-
134
- if (groupId) {
135
- // Regenerate the file for the affected group
136
- await regenerateTemplateStepGroupFile(groupId)
137
- }
138
- } catch (error) {
139
- console.error(`Failed to handle template step change for step ${templateStepId}:`, error)
140
- throw new Error(`File update failed: ${error}`)
141
- }
142
- }
143
-
144
- /**
145
- * Handles file regeneration when a template step is moved between groups
146
- * This is a special case that requires regenerating files for both groups
147
- */
148
- export async function handleTemplateStepGroupChange(
149
- oldGroupId: string | null,
150
- newGroupId: string | null,
151
- ): Promise<void> {
152
- try {
153
- // Regenerate file for the old group (if it exists)
154
- if (oldGroupId) {
155
- await regenerateTemplateStepGroupFile(oldGroupId)
156
- }
157
-
158
- // Regenerate file for the new group (if it exists)
159
- if (newGroupId) {
160
- await regenerateTemplateStepGroupFile(newGroupId)
161
- }
162
- } catch (error) {
163
- console.error(`Failed to handle template step group change:`, error)
164
- throw new Error(`File update failed: ${error}`)
165
- }
166
- }
1
+ import prisma from '@/config/db-config'
2
+ import { writeTemplateStepFile, deleteTemplateStepFile, generateFileContent } from './template-step-file-generator'
3
+ import { TemplateStepGroupType } from '@prisma/client'
4
+
5
+ // TemplateStepGroupType helper - will be available from @prisma/client after migration
6
+ type TemplateStepGroupTypeLocal = 'ACTION' | 'VALIDATION'
7
+
8
+ // Type helper to safely extract type from Prisma templateStepGroup records
9
+ type TemplateStepGroupWithType = {
10
+ id: string
11
+ name: string
12
+ description: string | null
13
+ type?: TemplateStepGroupTypeLocal
14
+ createdAt: Date
15
+ updatedAt: Date
16
+ }
17
+
18
+ function getGroupType(group: unknown): TemplateStepGroupTypeLocal {
19
+ const groupWithType = group as TemplateStepGroupWithType
20
+ const type = groupWithType.type
21
+ if (type === 'VALIDATION' || type === 'ACTION') {
22
+ return type
23
+ }
24
+ return 'ACTION' // default
25
+ }
26
+
27
+ /**
28
+ * Regenerates the file for a specific template step group
29
+ * This function is called whenever template steps in a group change
30
+ */
31
+ export async function regenerateTemplateStepGroupFile(groupId: string): Promise<void> {
32
+ try {
33
+ // Get the template step group with all its template steps
34
+ const group = await prisma.templateStepGroup.findUnique({
35
+ where: { id: groupId },
36
+ include: {
37
+ templateSteps: {
38
+ orderBy: {
39
+ // Order by creation time or any other field you prefer
40
+ createdAt: 'asc',
41
+ },
42
+ },
43
+ },
44
+ })
45
+
46
+ if (!group) {
47
+ throw new Error(`Template step group with ID ${groupId} not found`)
48
+ }
49
+
50
+ // Generate file content from template steps
51
+ const content = generateFileContent(group.templateSteps)
52
+
53
+ // Write the file
54
+ const type = getGroupType(group)
55
+ await writeTemplateStepFile(group.name, content, type)
56
+
57
+ console.log(`File regenerated for template step group: ${group.name}`)
58
+ } catch (error) {
59
+ console.error(`Failed to regenerate file for template step group ${groupId}:`, error)
60
+ throw new Error(`File regeneration failed: ${error}`)
61
+ }
62
+ }
63
+
64
+ /**
65
+ * Creates a placeholder file for a new template step group
66
+ * Called when a new group is created
67
+ * @deprecated Use createTemplateStepGroupFile from template-step-file-manager-intelligent.ts instead
68
+ */
69
+ export async function createTemplateStepGroupFile(
70
+ groupName: string,
71
+ type: TemplateStepGroupType | string = 'ACTION',
72
+ ): Promise<void> {
73
+ try {
74
+ // Create empty placeholder content with required imports
75
+ const placeholderContent =
76
+ '// This file is generated automatically. Add template steps to this group to generate content.'
77
+
78
+ // Write the placeholder file
79
+ await writeTemplateStepFile(groupName, placeholderContent, type)
80
+
81
+ console.log(`Placeholder file created for template step group: ${groupName}`)
82
+ } catch (error) {
83
+ console.error(`Failed to create placeholder file for group "${groupName}":`, error)
84
+ throw new Error(`File creation failed: ${error}`)
85
+ }
86
+ }
87
+
88
+ /**
89
+ * Deletes the file for a template step group
90
+ * Called when a group is deleted
91
+ * @deprecated Use removeTemplateStepGroupFile from template-step-file-manager-intelligent.ts instead
92
+ */
93
+ export async function removeTemplateStepGroupFile(
94
+ groupName: string,
95
+ type: TemplateStepGroupType | string = 'ACTION',
96
+ ): Promise<void> {
97
+ try {
98
+ await deleteTemplateStepFile(groupName, type)
99
+
100
+ console.log(`File deleted for template step group: ${groupName}`)
101
+ } catch (error) {
102
+ console.error(`Failed to delete file for group "${groupName}":`, error)
103
+ throw new Error(`File deletion failed: ${error}`)
104
+ }
105
+ }
106
+
107
+ /**
108
+ * Handles file regeneration when a template step is created, updated, or deleted
109
+ * This function determines which groups need file regeneration
110
+ */
111
+ export async function handleTemplateStepChange(
112
+ templateStepId: string,
113
+ operation: 'create' | 'update' | 'delete',
114
+ ): Promise<void> {
115
+ try {
116
+ let groupId: string | null = null
117
+
118
+ if (operation === 'delete') {
119
+ // For delete operations, we need to get the group ID before deletion
120
+ const step = await prisma.templateStep.findUnique({
121
+ where: { id: templateStepId },
122
+ select: { templateStepGroupId: true },
123
+ })
124
+ groupId = step?.templateStepGroupId || null
125
+ } else {
126
+ // For create/update operations, get the current group ID
127
+ const step = await prisma.templateStep.findUnique({
128
+ where: { id: templateStepId },
129
+ select: { templateStepGroupId: true },
130
+ })
131
+ groupId = step?.templateStepGroupId || null
132
+ }
133
+
134
+ if (groupId) {
135
+ // Regenerate the file for the affected group
136
+ await regenerateTemplateStepGroupFile(groupId)
137
+ }
138
+ } catch (error) {
139
+ console.error(`Failed to handle template step change for step ${templateStepId}:`, error)
140
+ throw new Error(`File update failed: ${error}`)
141
+ }
142
+ }
143
+
144
+ /**
145
+ * Handles file regeneration when a template step is moved between groups
146
+ * This is a special case that requires regenerating files for both groups
147
+ */
148
+ export async function handleTemplateStepGroupChange(
149
+ oldGroupId: string | null,
150
+ newGroupId: string | null,
151
+ ): Promise<void> {
152
+ try {
153
+ // Regenerate file for the old group (if it exists)
154
+ if (oldGroupId) {
155
+ await regenerateTemplateStepGroupFile(oldGroupId)
156
+ }
157
+
158
+ // Regenerate file for the new group (if it exists)
159
+ if (newGroupId) {
160
+ await regenerateTemplateStepGroupFile(newGroupId)
161
+ }
162
+ } catch (error) {
163
+ console.error(`Failed to handle template step group change:`, error)
164
+ throw new Error(`File update failed: ${error}`)
165
+ }
166
+ }
@@ -1,31 +1,31 @@
1
- import { clsx, type ClassValue } from 'clsx'
2
- import { twMerge } from 'tailwind-merge'
3
- export function cn(...inputs: ClassValue[]) {
4
- return twMerge(clsx(inputs))
5
- }
6
-
7
- export function calculateCompletionPercentage(total: number, completed: number) {
8
- return Math.round((completed / total) * 100)
9
- }
10
-
11
- /**
12
- * Formats a date to show only date and time (without seconds/milliseconds)
13
- * @param date - Date string or Date object
14
- * @returns Formatted date string in format: "MM/DD/YYYY, HH:MM AM/PM"
15
- */
16
- export function formatDateTime(date: string | Date | null | undefined): string {
17
- if (!date) return '-'
18
-
19
- const dateObj = typeof date === 'string' ? new Date(date) : date
20
-
21
- if (isNaN(dateObj.getTime())) return '-'
22
-
23
- return dateObj.toLocaleString('en-US', {
24
- year: 'numeric',
25
- month: '2-digit',
26
- day: '2-digit',
27
- hour: '2-digit',
28
- minute: '2-digit',
29
- hour12: true,
30
- })
31
- }
1
+ import { clsx, type ClassValue } from 'clsx'
2
+ import { twMerge } from 'tailwind-merge'
3
+ export function cn(...inputs: ClassValue[]) {
4
+ return twMerge(clsx(inputs))
5
+ }
6
+
7
+ export function calculateCompletionPercentage(total: number, completed: number) {
8
+ return Math.round((completed / total) * 100)
9
+ }
10
+
11
+ /**
12
+ * Formats a date to show only date and time (without seconds/milliseconds)
13
+ * @param date - Date string or Date object
14
+ * @returns Formatted date string in format: "MM/DD/YYYY, HH:MM AM/PM"
15
+ */
16
+ export function formatDateTime(date: string | Date | null | undefined): string {
17
+ if (!date) return '-'
18
+
19
+ const dateObj = typeof date === 'string' ? new Date(date) : date
20
+
21
+ if (isNaN(dateObj.getTime())) return '-'
22
+
23
+ return dateObj.toLocaleString('en-US', {
24
+ year: 'numeric',
25
+ month: '2-digit',
26
+ day: '2-digit',
27
+ hour: '2-digit',
28
+ minute: '2-digit',
29
+ hour12: true,
30
+ })
31
+ }