@sfdc-webapps/cli 1.0.2

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 (405) hide show
  1. package/README.md +1414 -0
  2. package/dist/commands/apply-patches.d.ts +23 -0
  3. package/dist/commands/apply-patches.d.ts.map +1 -0
  4. package/dist/commands/apply-patches.js +524 -0
  5. package/dist/commands/apply-patches.js.map +1 -0
  6. package/dist/commands/new-app-feature.d.ts +7 -0
  7. package/dist/commands/new-app-feature.d.ts.map +1 -0
  8. package/dist/commands/new-app-feature.js +166 -0
  9. package/dist/commands/new-app-feature.js.map +1 -0
  10. package/dist/commands/new-app.d.ts +1 -0
  11. package/dist/commands/new-app.d.ts.map +1 -0
  12. package/dist/commands/new-app.js +2 -0
  13. package/dist/commands/new-app.js.map +1 -0
  14. package/dist/commands/watch-patches.d.ts +6 -0
  15. package/dist/commands/watch-patches.d.ts.map +1 -0
  16. package/dist/commands/watch-patches.js +152 -0
  17. package/dist/commands/watch-patches.js.map +1 -0
  18. package/dist/core/dependency-resolver.d.ts +40 -0
  19. package/dist/core/dependency-resolver.d.ts.map +1 -0
  20. package/dist/core/dependency-resolver.js +122 -0
  21. package/dist/core/dependency-resolver.js.map +1 -0
  22. package/dist/core/file-operations.d.ts +37 -0
  23. package/dist/core/file-operations.d.ts.map +1 -0
  24. package/dist/core/file-operations.js +201 -0
  25. package/dist/core/file-operations.js.map +1 -0
  26. package/dist/core/package-json-merger.d.ts +30 -0
  27. package/dist/core/package-json-merger.d.ts.map +1 -0
  28. package/dist/core/package-json-merger.js +104 -0
  29. package/dist/core/package-json-merger.js.map +1 -0
  30. package/dist/core/patch-loader.d.ts +17 -0
  31. package/dist/core/patch-loader.d.ts.map +1 -0
  32. package/dist/core/patch-loader.js +100 -0
  33. package/dist/core/patch-loader.js.map +1 -0
  34. package/dist/index.d.ts +3 -0
  35. package/dist/index.d.ts.map +1 -0
  36. package/dist/index.js +90 -0
  37. package/dist/index.js.map +1 -0
  38. package/dist/types.d.ts +21 -0
  39. package/dist/types.d.ts.map +1 -0
  40. package/dist/types.js +2 -0
  41. package/dist/types.js.map +1 -0
  42. package/dist/utils/debounce.d.ts +6 -0
  43. package/dist/utils/debounce.d.ts.map +1 -0
  44. package/dist/utils/debounce.js +19 -0
  45. package/dist/utils/debounce.js.map +1 -0
  46. package/dist/utils/import-merger.d.ts +12 -0
  47. package/dist/utils/import-merger.d.ts.map +1 -0
  48. package/dist/utils/import-merger.js +240 -0
  49. package/dist/utils/import-merger.js.map +1 -0
  50. package/dist/utils/logger.d.ts +6 -0
  51. package/dist/utils/logger.d.ts.map +1 -0
  52. package/dist/utils/logger.js +17 -0
  53. package/dist/utils/logger.js.map +1 -0
  54. package/dist/utils/path-mappings.d.ts +88 -0
  55. package/dist/utils/path-mappings.d.ts.map +1 -0
  56. package/dist/utils/path-mappings.js +138 -0
  57. package/dist/utils/path-mappings.js.map +1 -0
  58. package/dist/utils/paths.d.ts +43 -0
  59. package/dist/utils/paths.d.ts.map +1 -0
  60. package/dist/utils/paths.js +107 -0
  61. package/dist/utils/paths.js.map +1 -0
  62. package/dist/utils/route-merger.d.ts +107 -0
  63. package/dist/utils/route-merger.d.ts.map +1 -0
  64. package/dist/utils/route-merger.js +303 -0
  65. package/dist/utils/route-merger.js.map +1 -0
  66. package/dist/utils/validation.d.ts +29 -0
  67. package/dist/utils/validation.d.ts.map +1 -0
  68. package/dist/utils/validation.js +109 -0
  69. package/dist/utils/validation.js.map +1 -0
  70. package/package.json +39 -0
  71. package/src/commands/apply-patches.ts +594 -0
  72. package/src/commands/new-app-feature.ts +203 -0
  73. package/src/commands/new-app.ts +0 -0
  74. package/src/commands/watch-patches.ts +173 -0
  75. package/src/core/dependency-resolver.ts +175 -0
  76. package/src/core/file-operations.ts +265 -0
  77. package/src/core/package-json-merger.ts +129 -0
  78. package/src/core/patch-loader.ts +128 -0
  79. package/src/index.ts +95 -0
  80. package/src/types.ts +23 -0
  81. package/src/utils/debounce.ts +23 -0
  82. package/src/utils/import-merger.ts +293 -0
  83. package/src/utils/logger.ts +21 -0
  84. package/src/utils/path-mappings.ts +154 -0
  85. package/src/utils/paths.ts +121 -0
  86. package/src/utils/route-merger.ts +357 -0
  87. package/src/utils/validation.ts +150 -0
  88. package/test/e2e/E2E_TEST_FIXTURES.md +509 -0
  89. package/test/e2e/apply-patches.spec.ts +861 -0
  90. package/test/e2e/fixtures/base-app/digitalExperiences/webApplications/base-app/package.json +10 -0
  91. package/test/e2e/fixtures/base-app/digitalExperiences/webApplications/base-app/src/appLayout.tsx +27 -0
  92. package/test/e2e/fixtures/base-app/digitalExperiences/webApplications/base-app/src/home.tsx +8 -0
  93. package/test/e2e/fixtures/base-app/digitalExperiences/webApplications/base-app/src/index.tsx +10 -0
  94. package/test/e2e/fixtures/base-app/digitalExperiences/webApplications/base-app/src/old-page.tsx +8 -0
  95. package/test/e2e/fixtures/base-app/digitalExperiences/webApplications/base-app/src/routes.tsx +23 -0
  96. package/test/e2e/fixtures/base-app/digitalExperiences/webApplications/base-app/src/styles/global.css +14 -0
  97. package/test/e2e/fixtures/basic-operations/dep-chain-linear/feature.ts +11 -0
  98. package/test/e2e/fixtures/basic-operations/dep-chain-linear/template/digitalExperiences/webApplications/dep-chain-linear/src/__inherit__appLayout.tsx +27 -0
  99. package/test/e2e/fixtures/basic-operations/dep-chain-linear/template/digitalExperiences/webApplications/dep-chain-linear/src/contact.tsx +8 -0
  100. package/test/e2e/fixtures/basic-operations/dep-chain-linear/template/digitalExperiences/webApplications/dep-chain-linear/src/routes.tsx +17 -0
  101. package/test/e2e/fixtures/basic-operations/feature-file-inherit-route-add/feature.ts +10 -0
  102. package/test/e2e/fixtures/basic-operations/feature-file-inherit-route-add/template/digitalExperiences/webApplications/feature-file-inherit-route-add/src/__inherit__appLayout.tsx +27 -0
  103. package/test/e2e/fixtures/basic-operations/feature-file-inherit-route-add/template/digitalExperiences/webApplications/feature-file-inherit-route-add/src/__inherit__home.tsx +0 -0
  104. package/test/e2e/fixtures/basic-operations/feature-file-inherit-route-add/template/digitalExperiences/webApplications/feature-file-inherit-route-add/src/about.tsx +8 -0
  105. package/test/e2e/fixtures/basic-operations/feature-file-inherit-route-add/template/digitalExperiences/webApplications/feature-file-inherit-route-add/src/routes.tsx +17 -0
  106. package/test/e2e/fixtures/basic-operations/feature-file-prepend-append/feature.ts +10 -0
  107. package/test/e2e/fixtures/basic-operations/feature-file-prepend-append/template/digitalExperiences/webApplications/feature-file-prepend-append/src/__inherit__appLayout.tsx +27 -0
  108. package/test/e2e/fixtures/basic-operations/feature-file-prepend-append/template/digitalExperiences/webApplications/feature-file-prepend-append/src/__prepend__index.tsx +2 -0
  109. package/test/e2e/fixtures/basic-operations/feature-file-prepend-append/template/digitalExperiences/webApplications/feature-file-prepend-append/src/routes.tsx +17 -0
  110. package/test/e2e/fixtures/basic-operations/feature-file-prepend-append/template/digitalExperiences/webApplications/feature-file-prepend-append/src/settings.tsx +9 -0
  111. package/test/e2e/fixtures/basic-operations/feature-file-prepend-append/template/digitalExperiences/webApplications/feature-file-prepend-append/src/styles/__append__global.css +10 -0
  112. package/test/e2e/fixtures/basic-operations/feature-file-route-delete/feature.ts +10 -0
  113. package/test/e2e/fixtures/basic-operations/feature-file-route-delete/template/digitalExperiences/webApplications/feature-file-route-delete/src/__delete__old-page.tsx +2 -0
  114. package/test/e2e/fixtures/basic-operations/feature-file-route-delete/template/digitalExperiences/webApplications/feature-file-route-delete/src/__inherit__appLayout.tsx +27 -0
  115. package/test/e2e/fixtures/basic-operations/feature-file-route-delete/template/digitalExperiences/webApplications/feature-file-route-delete/src/routes.tsx +16 -0
  116. package/test/e2e/fixtures/composition-5-features/5-features-about/feature.ts +3 -0
  117. package/test/e2e/fixtures/composition-5-features/5-features-about/template/digitalExperiences/webApplications/5-features-about/src/about.tsx +8 -0
  118. package/test/e2e/fixtures/composition-5-features/5-features-about/template/digitalExperiences/webApplications/5-features-about/src/routes.tsx +17 -0
  119. package/test/e2e/fixtures/composition-5-features/5-features-analytics/feature.ts +3 -0
  120. package/test/e2e/fixtures/composition-5-features/5-features-analytics/template/digitalExperiences/webApplications/5-features-analytics/src/__prepend__index.tsx +2 -0
  121. package/test/e2e/fixtures/composition-5-features/5-features-footer/feature.ts +3 -0
  122. package/test/e2e/fixtures/composition-5-features/5-features-footer/template/digitalExperiences/webApplications/5-features-footer/src/footer.tsx +7 -0
  123. package/test/e2e/fixtures/composition-5-features/5-features-footer/template/digitalExperiences/webApplications/5-features-footer/src/routes.tsx +17 -0
  124. package/test/e2e/fixtures/composition-5-features/5-features-navigation/feature.ts +3 -0
  125. package/test/e2e/fixtures/composition-5-features/5-features-navigation/template/digitalExperiences/webApplications/5-features-navigation/src/navigation.tsx +7 -0
  126. package/test/e2e/fixtures/composition-5-features/5-features-navigation/template/digitalExperiences/webApplications/5-features-navigation/src/routes.tsx +17 -0
  127. package/test/e2e/fixtures/composition-5-features/5-features-theme/feature.ts +3 -0
  128. package/test/e2e/fixtures/composition-5-features/5-features-theme/template/digitalExperiences/webApplications/5-features-theme/src/styles/__append__global.css +5 -0
  129. package/test/e2e/fixtures/composition-append/composition-append-1/feature.ts +10 -0
  130. package/test/e2e/fixtures/composition-append/composition-append-1/template/digitalExperiences/webApplications/composition-append-1/src/styles/__append__global.css +4 -0
  131. package/test/e2e/fixtures/composition-append/composition-append-2/feature.ts +10 -0
  132. package/test/e2e/fixtures/composition-append/composition-append-2/template/digitalExperiences/webApplications/composition-append-2/src/styles/__append__global.css +4 -0
  133. package/test/e2e/fixtures/composition-append/composition-append-3/feature.ts +10 -0
  134. package/test/e2e/fixtures/composition-append/composition-append-3/template/digitalExperiences/webApplications/composition-append-3/src/styles/__append__global.css +4 -0
  135. package/test/e2e/fixtures/composition-inherit-modify/composition-inherit-layout/feature.ts +3 -0
  136. package/test/e2e/fixtures/composition-inherit-modify/composition-inherit-layout/template/digitalExperiences/webApplications/composition-inherit-layout/src/__inherit__appLayout.tsx +1 -0
  137. package/test/e2e/fixtures/composition-inherit-modify/composition-modify-layout/feature.ts +3 -0
  138. package/test/e2e/fixtures/composition-inherit-modify/composition-modify-layout/template/digitalExperiences/webApplications/composition-modify-layout/src/__append__appLayout.tsx +2 -0
  139. package/test/e2e/fixtures/composition-prepend/composition-prepend-1/feature.ts +10 -0
  140. package/test/e2e/fixtures/composition-prepend/composition-prepend-1/template/digitalExperiences/webApplications/composition-prepend-1/src/__prepend__index.tsx +2 -0
  141. package/test/e2e/fixtures/composition-prepend/composition-prepend-2/feature.ts +10 -0
  142. package/test/e2e/fixtures/composition-prepend/composition-prepend-2/template/digitalExperiences/webApplications/composition-prepend-2/src/__prepend__index.tsx +2 -0
  143. package/test/e2e/fixtures/composition-prepend/composition-prepend-3/feature.ts +10 -0
  144. package/test/e2e/fixtures/composition-prepend/composition-prepend-3/template/digitalExperiences/webApplications/composition-prepend-3/src/__prepend__index.tsx +2 -0
  145. package/test/e2e/fixtures/dep-chain-long/dep-chain-a/feature.ts +11 -0
  146. package/test/e2e/fixtures/dep-chain-long/dep-chain-a/template/digitalExperiences/webApplications/dep-chain-a/src/page-a.tsx +8 -0
  147. package/test/e2e/fixtures/dep-chain-long/dep-chain-a/template/digitalExperiences/webApplications/dep-chain-a/src/routes.tsx +17 -0
  148. package/test/e2e/fixtures/dep-chain-long/dep-chain-b/feature.ts +11 -0
  149. package/test/e2e/fixtures/dep-chain-long/dep-chain-b/template/digitalExperiences/webApplications/dep-chain-b/src/page-b.tsx +8 -0
  150. package/test/e2e/fixtures/dep-chain-long/dep-chain-b/template/digitalExperiences/webApplications/dep-chain-b/src/routes.tsx +17 -0
  151. package/test/e2e/fixtures/dep-chain-long/dep-chain-c/feature.ts +11 -0
  152. package/test/e2e/fixtures/dep-chain-long/dep-chain-c/template/digitalExperiences/webApplications/dep-chain-c/src/page-c.tsx +8 -0
  153. package/test/e2e/fixtures/dep-chain-long/dep-chain-c/template/digitalExperiences/webApplications/dep-chain-c/src/routes.tsx +17 -0
  154. package/test/e2e/fixtures/dep-chain-long/dep-chain-d/feature.ts +10 -0
  155. package/test/e2e/fixtures/dep-chain-long/dep-chain-d/template/digitalExperiences/webApplications/dep-chain-d/src/page-d.tsx +8 -0
  156. package/test/e2e/fixtures/dep-chain-long/dep-chain-d/template/digitalExperiences/webApplications/dep-chain-d/src/routes.tsx +17 -0
  157. package/test/e2e/fixtures/dep-circular/dep-circular-a/feature.ts +11 -0
  158. package/test/e2e/fixtures/dep-circular/dep-circular-a/template/digitalExperiences/webApplications/dep-circular-a/src/page-a.tsx +8 -0
  159. package/test/e2e/fixtures/dep-circular/dep-circular-b/feature.ts +11 -0
  160. package/test/e2e/fixtures/dep-circular/dep-circular-b/template/digitalExperiences/webApplications/dep-circular-b/src/page-b.tsx +8 -0
  161. package/test/e2e/fixtures/dep-complex-graph/README.md +119 -0
  162. package/test/e2e/fixtures/dep-complex-graph/create-placeholders.sh +25 -0
  163. package/test/e2e/fixtures/dep-complex-graph/dep-complex-graph-auth/feature.ts +14 -0
  164. package/test/e2e/fixtures/dep-complex-graph/dep-complex-graph-auth/template/digitalExperiences/webApplications/dep-complex-graph-auth/src/__delete__old-page.tsx +1 -0
  165. package/test/e2e/fixtures/dep-complex-graph/dep-complex-graph-auth/template/digitalExperiences/webApplications/dep-complex-graph-auth/src/__inherit__appLayout.tsx +1 -0
  166. package/test/e2e/fixtures/dep-complex-graph/dep-complex-graph-auth/template/digitalExperiences/webApplications/dep-complex-graph-auth/src/login.tsx +8 -0
  167. package/test/e2e/fixtures/dep-complex-graph/dep-complex-graph-auth/template/digitalExperiences/webApplications/dep-complex-graph-auth/src/routes.tsx +29 -0
  168. package/test/e2e/fixtures/dep-complex-graph/dep-complex-graph-auth/template/digitalExperiences/webApplications/dep-complex-graph-auth/src/signup.tsx +1 -0
  169. package/test/e2e/fixtures/dep-complex-graph/dep-complex-graph-dashboard/feature.ts +14 -0
  170. package/test/e2e/fixtures/dep-complex-graph/dep-complex-graph-dashboard/template/digitalExperiences/webApplications/dep-complex-graph-dashboard/src/__inherit__appLayout.tsx +1 -0
  171. package/test/e2e/fixtures/dep-complex-graph/dep-complex-graph-dashboard/template/digitalExperiences/webApplications/dep-complex-graph-dashboard/src/analytics.tsx +1 -0
  172. package/test/e2e/fixtures/dep-complex-graph/dep-complex-graph-dashboard/template/digitalExperiences/webApplications/dep-complex-graph-dashboard/src/dashboard.tsx +8 -0
  173. package/test/e2e/fixtures/dep-complex-graph/dep-complex-graph-dashboard/template/digitalExperiences/webApplications/dep-complex-graph-dashboard/src/reports.tsx +1 -0
  174. package/test/e2e/fixtures/dep-complex-graph/dep-complex-graph-dashboard/template/digitalExperiences/webApplications/dep-complex-graph-dashboard/src/routes.tsx +32 -0
  175. package/test/e2e/fixtures/dep-complex-graph/dep-complex-graph-profile/feature.ts +14 -0
  176. package/test/e2e/fixtures/dep-complex-graph/dep-complex-graph-profile/template/digitalExperiences/webApplications/dep-complex-graph-profile/src/__inherit__appLayout.tsx +1 -0
  177. package/test/e2e/fixtures/dep-complex-graph/dep-complex-graph-profile/template/digitalExperiences/webApplications/dep-complex-graph-profile/src/profile-edit.tsx +1 -0
  178. package/test/e2e/fixtures/dep-complex-graph/dep-complex-graph-profile/template/digitalExperiences/webApplications/dep-complex-graph-profile/src/profile.tsx +8 -0
  179. package/test/e2e/fixtures/dep-complex-graph/dep-complex-graph-profile/template/digitalExperiences/webApplications/dep-complex-graph-profile/src/routes.tsx +26 -0
  180. package/test/e2e/fixtures/dep-complex-graph/dep-complex-graph-shared-components/feature.ts +14 -0
  181. package/test/e2e/fixtures/dep-complex-graph/dep-complex-graph-shared-components/template/digitalExperiences/webApplications/dep-complex-graph-shared-components/src/__inherit__appLayout.tsx +1 -0
  182. package/test/e2e/fixtures/dep-complex-graph/dep-complex-graph-shared-components/template/digitalExperiences/webApplications/dep-complex-graph-shared-components/src/components.tsx +8 -0
  183. package/test/e2e/fixtures/dep-complex-graph/dep-complex-graph-shared-components/template/digitalExperiences/webApplications/dep-complex-graph-shared-components/src/routes.tsx +18 -0
  184. package/test/e2e/fixtures/dep-complex-graph/dep-complex-graph-shared-types/feature.ts +10 -0
  185. package/test/e2e/fixtures/dep-complex-graph/dep-complex-graph-shared-types/template/digitalExperiences/webApplications/dep-complex-graph-shared-types/src/__inherit__appLayout.tsx +1 -0
  186. package/test/e2e/fixtures/dep-complex-graph/dep-complex-graph-shared-types/template/digitalExperiences/webApplications/dep-complex-graph-shared-types/src/routes.tsx +17 -0
  187. package/test/e2e/fixtures/dep-complex-graph/dep-complex-graph-shared-types/template/digitalExperiences/webApplications/dep-complex-graph-shared-types/src/types.tsx +8 -0
  188. package/test/e2e/fixtures/dep-complex-graph/dep-complex-graph-shared-utils/feature.ts +10 -0
  189. package/test/e2e/fixtures/dep-complex-graph/dep-complex-graph-shared-utils/template/digitalExperiences/webApplications/dep-complex-graph-shared-utils/src/__inherit__appLayout.tsx +1 -0
  190. package/test/e2e/fixtures/dep-complex-graph/dep-complex-graph-shared-utils/template/digitalExperiences/webApplications/dep-complex-graph-shared-utils/src/routes.tsx +18 -0
  191. package/test/e2e/fixtures/dep-complex-graph/dep-complex-graph-shared-utils/template/digitalExperiences/webApplications/dep-complex-graph-shared-utils/src/tools.tsx +1 -0
  192. package/test/e2e/fixtures/dep-complex-graph/feature.ts +15 -0
  193. package/test/e2e/fixtures/dep-complex-graph/template/digitalExperiences/webApplications/dep-complex-graph/src/__inherit__appLayout.tsx +1 -0
  194. package/test/e2e/fixtures/dep-complex-graph/template/digitalExperiences/webApplications/dep-complex-graph/src/admin-dashboard.tsx +1 -0
  195. package/test/e2e/fixtures/dep-complex-graph/template/digitalExperiences/webApplications/dep-complex-graph/src/admin-layout.tsx +1 -0
  196. package/test/e2e/fixtures/dep-complex-graph/template/digitalExperiences/webApplications/dep-complex-graph/src/routes.tsx +24 -0
  197. package/test/e2e/fixtures/dep-diamond/dep-diamond-left/feature.ts +11 -0
  198. package/test/e2e/fixtures/dep-diamond/dep-diamond-left/template/digitalExperiences/webApplications/dep-diamond-left/src/left-page.tsx +8 -0
  199. package/test/e2e/fixtures/dep-diamond/dep-diamond-left/template/digitalExperiences/webApplications/dep-diamond-left/src/routes.tsx +17 -0
  200. package/test/e2e/fixtures/dep-diamond/dep-diamond-right/feature.ts +11 -0
  201. package/test/e2e/fixtures/dep-diamond/dep-diamond-right/template/digitalExperiences/webApplications/dep-diamond-right/src/right-page.tsx +8 -0
  202. package/test/e2e/fixtures/dep-diamond/dep-diamond-right/template/digitalExperiences/webApplications/dep-diamond-right/src/routes.tsx +17 -0
  203. package/test/e2e/fixtures/dep-diamond/dep-diamond-shared/feature.ts +10 -0
  204. package/test/e2e/fixtures/dep-diamond/dep-diamond-shared/template/digitalExperiences/webApplications/dep-diamond-shared/src/routes.tsx +17 -0
  205. package/test/e2e/fixtures/dep-diamond/dep-diamond-shared/template/digitalExperiences/webApplications/dep-diamond-shared/src/shared-utils.tsx +8 -0
  206. package/test/e2e/fixtures/edges/edge-binary-files/feature.ts +13 -0
  207. package/test/e2e/fixtures/edges/edge-binary-files/template/digitalExperiences/webApplications/edge-binary-files/src/__inherit__appLayout.tsx +1 -0
  208. package/test/e2e/fixtures/edges/edge-binary-files/template/digitalExperiences/webApplications/edge-binary-files/src/assets/test-image.png +0 -0
  209. package/test/e2e/fixtures/edges/edge-binary-files/template/digitalExperiences/webApplications/edge-binary-files/src/placeholder.tsx +0 -0
  210. package/test/e2e/fixtures/edges/edge-conflicting-prefixes/feature.ts +13 -0
  211. package/test/e2e/fixtures/edges/edge-conflicting-prefixes/template/digitalExperiences/webApplications/edge-conflicting-prefixes/src/__inherit____delete__conflicting.tsx +5 -0
  212. package/test/e2e/fixtures/edges/edge-conflicting-prefixes/template/digitalExperiences/webApplications/edge-conflicting-prefixes/src/placeholder.tsx +0 -0
  213. package/test/e2e/fixtures/edges/edge-empty-feature/feature.ts +16 -0
  214. package/test/e2e/fixtures/edges/edge-empty-feature/template/digitalExperiences/webApplications/edge-empty-feature/src/placeholder.tsx +0 -0
  215. package/test/e2e/fixtures/edges/edge-invalid-routes/feature.ts +12 -0
  216. package/test/e2e/fixtures/edges/edge-invalid-routes/template/digitalExperiences/webApplications/edge-invalid-routes/src/placeholder.tsx +0 -0
  217. package/test/e2e/fixtures/edges/edge-invalid-routes/template/digitalExperiences/webApplications/edge-invalid-routes/src/routes.tsx +8 -0
  218. package/test/e2e/fixtures/edges/edge-line-endings/feature.ts +13 -0
  219. package/test/e2e/fixtures/edges/edge-line-endings/template/digitalExperiences/webApplications/edge-line-endings/src/__prepend__index.tsx +2 -0
  220. package/test/e2e/fixtures/edges/edge-line-endings/template/digitalExperiences/webApplications/edge-line-endings/src/crlf.tsx +4 -0
  221. package/test/e2e/fixtures/edges/edge-line-endings/template/digitalExperiences/webApplications/edge-line-endings/src/placeholder.tsx +0 -0
  222. package/test/e2e/fixtures/edges/edge-line-endings/template/digitalExperiences/webApplications/edge-line-endings/src/styles/__append__global.css +4 -0
  223. package/test/e2e/fixtures/edges/edge-missing-base-files/feature.ts +13 -0
  224. package/test/e2e/fixtures/edges/edge-missing-base-files/template/digitalExperiences/webApplications/edge-missing-base-files/src/__inherit__missing.tsx +1 -0
  225. package/test/e2e/fixtures/edges/edge-missing-base-files/template/digitalExperiences/webApplications/edge-missing-base-files/src/__prepend__nonexistent.tsx +2 -0
  226. package/test/e2e/fixtures/edges/edge-missing-base-files/template/digitalExperiences/webApplications/edge-missing-base-files/src/placeholder.tsx +0 -0
  227. package/test/e2e/fixtures/edges/edge-package-json-conflicts-a/feature.ts +14 -0
  228. package/test/e2e/fixtures/edges/edge-package-json-conflicts-a/template/digitalExperiences/webApplications/edge-package-json-conflicts-a/src/placeholder.tsx +1 -0
  229. package/test/e2e/fixtures/edges/edge-package-json-conflicts-b/feature.ts +14 -0
  230. package/test/e2e/fixtures/edges/edge-package-json-conflicts-b/template/digitalExperiences/webApplications/edge-package-json-conflicts-b/src/placeholder.tsx +1 -0
  231. package/test/e2e/fixtures/edges/edge-performance-many/feature.ts +26 -0
  232. package/test/e2e/fixtures/edges/edge-performance-many/template/digitalExperiences/webApplications/edge-performance-many/src/placeholder.tsx +0 -0
  233. package/test/e2e/fixtures/path-mappings/feature-custom-mapping/feature.ts +16 -0
  234. package/test/e2e/fixtures/path-mappings/feature-custom-mapping/template/web/src/custom-component.tsx +3 -0
  235. package/test/e2e/fixtures/path-mappings/feature-custom-mapping/template/web/src/routes.tsx +8 -0
  236. package/test/e2e/fixtures/path-mappings/feature-mixed-paths/feature.ts +7 -0
  237. package/test/e2e/fixtures/path-mappings/feature-mixed-paths/template/digitalExperiences/webApplications/feature-mixed-paths/assets/icon.svg +3 -0
  238. package/test/e2e/fixtures/path-mappings/feature-mixed-paths/template/webApp/src/mapped-component.tsx +3 -0
  239. package/test/e2e/fixtures/path-mappings/feature-mixed-paths/template/webApp/src/routes.tsx +8 -0
  240. package/test/e2e/fixtures/path-mappings/feature-with-webapp-mapping/feature.ts +7 -0
  241. package/test/e2e/fixtures/path-mappings/feature-with-webapp-mapping/template/webApp/src/app.tsx +3 -0
  242. package/test/e2e/fixtures/path-mappings/feature-with-webapp-mapping/template/webApp/src/routes.tsx +8 -0
  243. package/test/e2e/fixtures/path-mappings/feature-without-mapping/feature.ts +11 -0
  244. package/test/e2e/fixtures/path-mappings/feature-without-mapping/template/digitalExperiences/webApplications/feature-without-mapping/src/legacy-component.tsx +3 -0
  245. package/test/e2e/fixtures/path-mappings/feature-without-mapping/template/digitalExperiences/webApplications/feature-without-mapping/src/routes.tsx +8 -0
  246. package/test/e2e/fixtures/scenarios/scenario-authentication/feature.ts +10 -0
  247. package/test/e2e/fixtures/scenarios/scenario-authentication/template/digitalExperiences/webApplications/scenario-authentication/src/components/LoginForm.tsx +25 -0
  248. package/test/e2e/fixtures/scenarios/scenario-authentication/template/digitalExperiences/webApplications/scenario-authentication/src/context/AuthContext.tsx +28 -0
  249. package/test/e2e/fixtures/scenarios/scenario-authentication/template/digitalExperiences/webApplications/scenario-authentication/src/login.tsx +10 -0
  250. package/test/e2e/fixtures/scenarios/scenario-authentication/template/digitalExperiences/webApplications/scenario-authentication/src/placeholder.tsx +0 -0
  251. package/test/e2e/fixtures/scenarios/scenario-authentication/template/digitalExperiences/webApplications/scenario-authentication/src/routes.tsx +17 -0
  252. package/test/e2e/fixtures/scenarios/scenario-crud-contacts/feature.ts +11 -0
  253. package/test/e2e/fixtures/scenarios/scenario-crud-contacts/template/digitalExperiences/webApplications/scenario-crud-contacts/src/__inherit__appLayout.tsx +1 -0
  254. package/test/e2e/fixtures/scenarios/scenario-crud-contacts/template/digitalExperiences/webApplications/scenario-crud-contacts/src/components/ContactDetail.tsx +54 -0
  255. package/test/e2e/fixtures/scenarios/scenario-crud-contacts/template/digitalExperiences/webApplications/scenario-crud-contacts/src/components/ContactForm.tsx +146 -0
  256. package/test/e2e/fixtures/scenarios/scenario-crud-contacts/template/digitalExperiences/webApplications/scenario-crud-contacts/src/components/ContactList.tsx +77 -0
  257. package/test/e2e/fixtures/scenarios/scenario-crud-contacts/template/digitalExperiences/webApplications/scenario-crud-contacts/src/placeholder.tsx +0 -0
  258. package/test/e2e/fixtures/scenarios/scenario-crud-contacts/template/digitalExperiences/webApplications/scenario-crud-contacts/src/routes.tsx +36 -0
  259. package/test/e2e/fixtures/scenarios/scenario-crud-contacts/template/digitalExperiences/webApplications/scenario-crud-contacts/src/styles/__append__global.css +176 -0
  260. package/test/e2e/fixtures/scenarios/scenario-crud-contacts/template/digitalExperiences/webApplications/scenario-crud-contacts/src/utils/contactsApi.ts +42 -0
  261. package/test/e2e/fixtures/scenarios/scenario-navigation-menu/feature.ts +10 -0
  262. package/test/e2e/fixtures/scenarios/scenario-navigation-menu/template/digitalExperiences/webApplications/scenario-navigation-menu/src/__append__appLayout.tsx +4 -0
  263. package/test/e2e/fixtures/scenarios/scenario-navigation-menu/template/digitalExperiences/webApplications/scenario-navigation-menu/src/components/NavigationMenu.tsx +17 -0
  264. package/test/e2e/fixtures/scenarios/scenario-navigation-menu/template/digitalExperiences/webApplications/scenario-navigation-menu/src/placeholder.tsx +0 -0
  265. package/test/e2e/fixtures/single-operations/feature-file-append/feature.ts +10 -0
  266. package/test/e2e/fixtures/single-operations/feature-file-append/template/digitalExperiences/webApplications/feature-file-append/src/styles/__append__global.css +10 -0
  267. package/test/e2e/fixtures/single-operations/feature-file-inherit/feature.ts +10 -0
  268. package/test/e2e/fixtures/single-operations/feature-file-inherit/template/digitalExperiences/webApplications/feature-file-inherit/src/__inherit__appLayout.tsx +1 -0
  269. package/test/e2e/fixtures/single-operations/feature-file-inherit/template/digitalExperiences/webApplications/feature-file-inherit/src/__inherit__home.tsx +1 -0
  270. package/test/e2e/fixtures/single-operations/feature-file-prepend/feature.ts +10 -0
  271. package/test/e2e/fixtures/single-operations/feature-file-prepend/template/digitalExperiences/webApplications/feature-file-prepend/src/__prepend__index.tsx +2 -0
  272. package/test/e2e/fixtures/single-operations/feature-import-merge/feature.ts +10 -0
  273. package/test/e2e/fixtures/single-operations/feature-import-merge/template/digitalExperiences/webApplications/feature-import-merge/src/routes.tsx +18 -0
  274. package/test/e2e/fixtures/single-operations/feature-import-merge/template/digitalExperiences/webApplications/feature-import-merge/src/settings.tsx +8 -0
  275. package/test/e2e/fixtures/single-operations/feature-route-add/feature.ts +10 -0
  276. package/test/e2e/fixtures/single-operations/feature-route-add/template/digitalExperiences/webApplications/feature-route-add/src/about.tsx +8 -0
  277. package/test/e2e/fixtures/single-operations/feature-route-add/template/digitalExperiences/webApplications/feature-route-add/src/routes.tsx +23 -0
  278. package/test/e2e/fixtures/single-operations/feature-route-add/template/digitalExperiences/webApplications/feature-route-add/src/services.tsx +8 -0
  279. package/test/e2e/fixtures/watch/watch-add-delete-files/feature.ts +13 -0
  280. package/test/e2e/fixtures/watch/watch-add-delete-files/template/digitalExperiences/webApplications/watch-add-delete-files/src/initial.tsx +4 -0
  281. package/test/e2e/fixtures/watch/watch-add-delete-files/template/digitalExperiences/webApplications/watch-add-delete-files/src/placeholder.tsx +4 -0
  282. package/test/e2e/fixtures/watch/watch-basic/feature.ts +13 -0
  283. package/test/e2e/fixtures/watch/watch-basic/template/digitalExperiences/webApplications/watch-basic/src/placeholder.tsx +4 -0
  284. package/test/e2e/fixtures/watch/watch-basic/template/digitalExperiences/webApplications/watch-basic/src/watchTest.tsx +3 -0
  285. package/test/e2e/fixtures/watch/watch-debounce/feature.ts +13 -0
  286. package/test/e2e/fixtures/watch/watch-debounce/template/digitalExperiences/webApplications/watch-debounce/src/placeholder.tsx +4 -0
  287. package/test/e2e/fixtures/watch/watch-multiple-files/feature.ts +13 -0
  288. package/test/e2e/fixtures/watch/watch-multiple-files/template/digitalExperiences/webApplications/watch-multiple-files/src/components/WatchComponent.tsx +3 -0
  289. package/test/e2e/fixtures/watch/watch-multiple-files/template/digitalExperiences/webApplications/watch-multiple-files/src/placeholder.tsx +4 -0
  290. package/test/e2e/fixtures/watch/watch-multiple-files/template/digitalExperiences/webApplications/watch-multiple-files/src/styles/theme.css +4 -0
  291. package/test/e2e/gold/dep-chain-linear-apply/digitalExperiences/webApplications/dep-chain-linear/package.json +10 -0
  292. package/test/e2e/gold/dep-chain-linear-apply/digitalExperiences/webApplications/dep-chain-linear/src/about.tsx +8 -0
  293. package/test/e2e/gold/dep-chain-linear-apply/digitalExperiences/webApplications/dep-chain-linear/src/appLayout.tsx +27 -0
  294. package/test/e2e/gold/dep-chain-linear-apply/digitalExperiences/webApplications/dep-chain-linear/src/contact.tsx +8 -0
  295. package/test/e2e/gold/dep-chain-linear-apply/digitalExperiences/webApplications/dep-chain-linear/src/home.tsx +8 -0
  296. package/test/e2e/gold/dep-chain-linear-apply/digitalExperiences/webApplications/dep-chain-linear/src/index.tsx +10 -0
  297. package/test/e2e/gold/dep-chain-linear-apply/digitalExperiences/webApplications/dep-chain-linear/src/old-page.tsx +8 -0
  298. package/test/e2e/gold/dep-chain-linear-apply/digitalExperiences/webApplications/dep-chain-linear/src/routes.tsx +35 -0
  299. package/test/e2e/gold/dep-chain-linear-apply/digitalExperiences/webApplications/dep-chain-linear/src/styles/global.css +14 -0
  300. package/test/e2e/gold/dep-chain-long-apply/digitalExperiences/webApplications/dep-chain-a/package.json +10 -0
  301. package/test/e2e/gold/dep-chain-long-apply/digitalExperiences/webApplications/dep-chain-a/src/appLayout.tsx +27 -0
  302. package/test/e2e/gold/dep-chain-long-apply/digitalExperiences/webApplications/dep-chain-a/src/home.tsx +8 -0
  303. package/test/e2e/gold/dep-chain-long-apply/digitalExperiences/webApplications/dep-chain-a/src/index.tsx +10 -0
  304. package/test/e2e/gold/dep-chain-long-apply/digitalExperiences/webApplications/dep-chain-a/src/old-page.tsx +8 -0
  305. package/test/e2e/gold/dep-chain-long-apply/digitalExperiences/webApplications/dep-chain-a/src/page-a.tsx +8 -0
  306. package/test/e2e/gold/dep-chain-long-apply/digitalExperiences/webApplications/dep-chain-a/src/page-b.tsx +8 -0
  307. package/test/e2e/gold/dep-chain-long-apply/digitalExperiences/webApplications/dep-chain-a/src/page-c.tsx +8 -0
  308. package/test/e2e/gold/dep-chain-long-apply/digitalExperiences/webApplications/dep-chain-a/src/page-d.tsx +8 -0
  309. package/test/e2e/gold/dep-chain-long-apply/digitalExperiences/webApplications/dep-chain-a/src/routes.tsx +47 -0
  310. package/test/e2e/gold/dep-chain-long-apply/digitalExperiences/webApplications/dep-chain-a/src/styles/global.css +14 -0
  311. package/test/e2e/gold/dep-complex-graph-apply/digitalExperiences/webApplications/dep-complex-graph/package.json +10 -0
  312. package/test/e2e/gold/dep-complex-graph-apply/digitalExperiences/webApplications/dep-complex-graph/src/admin-dashboard.tsx +1 -0
  313. package/test/e2e/gold/dep-complex-graph-apply/digitalExperiences/webApplications/dep-complex-graph/src/admin-layout.tsx +1 -0
  314. package/test/e2e/gold/dep-complex-graph-apply/digitalExperiences/webApplications/dep-complex-graph/src/analytics.tsx +1 -0
  315. package/test/e2e/gold/dep-complex-graph-apply/digitalExperiences/webApplications/dep-complex-graph/src/appLayout.tsx +27 -0
  316. package/test/e2e/gold/dep-complex-graph-apply/digitalExperiences/webApplications/dep-complex-graph/src/components.tsx +8 -0
  317. package/test/e2e/gold/dep-complex-graph-apply/digitalExperiences/webApplications/dep-complex-graph/src/dashboard.tsx +8 -0
  318. package/test/e2e/gold/dep-complex-graph-apply/digitalExperiences/webApplications/dep-complex-graph/src/home.tsx +8 -0
  319. package/test/e2e/gold/dep-complex-graph-apply/digitalExperiences/webApplications/dep-complex-graph/src/index.tsx +10 -0
  320. package/test/e2e/gold/dep-complex-graph-apply/digitalExperiences/webApplications/dep-complex-graph/src/login.tsx +8 -0
  321. package/test/e2e/gold/dep-complex-graph-apply/digitalExperiences/webApplications/dep-complex-graph/src/profile-edit.tsx +1 -0
  322. package/test/e2e/gold/dep-complex-graph-apply/digitalExperiences/webApplications/dep-complex-graph/src/profile.tsx +8 -0
  323. package/test/e2e/gold/dep-complex-graph-apply/digitalExperiences/webApplications/dep-complex-graph/src/reports.tsx +1 -0
  324. package/test/e2e/gold/dep-complex-graph-apply/digitalExperiences/webApplications/dep-complex-graph/src/routes.tsx +94 -0
  325. package/test/e2e/gold/dep-complex-graph-apply/digitalExperiences/webApplications/dep-complex-graph/src/signup.tsx +1 -0
  326. package/test/e2e/gold/dep-complex-graph-apply/digitalExperiences/webApplications/dep-complex-graph/src/styles/global.css +14 -0
  327. package/test/e2e/gold/dep-complex-graph-apply/digitalExperiences/webApplications/dep-complex-graph/src/tools.tsx +1 -0
  328. package/test/e2e/gold/dep-complex-graph-apply/digitalExperiences/webApplications/dep-complex-graph/src/types.tsx +8 -0
  329. package/test/e2e/gold/feature-custom-mapping-apply/digitalExperiences/webApplications/feature-custom-mapping/package.json +10 -0
  330. package/test/e2e/gold/feature-custom-mapping-apply/digitalExperiences/webApplications/feature-custom-mapping/src/appLayout.tsx +27 -0
  331. package/test/e2e/gold/feature-custom-mapping-apply/digitalExperiences/webApplications/feature-custom-mapping/src/custom-component.tsx +3 -0
  332. package/test/e2e/gold/feature-custom-mapping-apply/digitalExperiences/webApplications/feature-custom-mapping/src/home.tsx +8 -0
  333. package/test/e2e/gold/feature-custom-mapping-apply/digitalExperiences/webApplications/feature-custom-mapping/src/index.tsx +10 -0
  334. package/test/e2e/gold/feature-custom-mapping-apply/digitalExperiences/webApplications/feature-custom-mapping/src/old-page.tsx +8 -0
  335. package/test/e2e/gold/feature-custom-mapping-apply/digitalExperiences/webApplications/feature-custom-mapping/src/routes.tsx +28 -0
  336. package/test/e2e/gold/feature-custom-mapping-apply/digitalExperiences/webApplications/feature-custom-mapping/src/styles/global.css +14 -0
  337. package/test/e2e/gold/feature-file-inherit-route-add-apply/digitalExperiences/webApplications/feature-file-inherit-route-add/package.json +10 -0
  338. package/test/e2e/gold/feature-file-inherit-route-add-apply/digitalExperiences/webApplications/feature-file-inherit-route-add/src/about.tsx +8 -0
  339. package/test/e2e/gold/feature-file-inherit-route-add-apply/digitalExperiences/webApplications/feature-file-inherit-route-add/src/appLayout.tsx +27 -0
  340. package/test/e2e/gold/feature-file-inherit-route-add-apply/digitalExperiences/webApplications/feature-file-inherit-route-add/src/home.tsx +8 -0
  341. package/test/e2e/gold/feature-file-inherit-route-add-apply/digitalExperiences/webApplications/feature-file-inherit-route-add/src/index.tsx +10 -0
  342. package/test/e2e/gold/feature-file-inherit-route-add-apply/digitalExperiences/webApplications/feature-file-inherit-route-add/src/old-page.tsx +8 -0
  343. package/test/e2e/gold/feature-file-inherit-route-add-apply/digitalExperiences/webApplications/feature-file-inherit-route-add/src/routes.tsx +29 -0
  344. package/test/e2e/gold/feature-file-inherit-route-add-apply/digitalExperiences/webApplications/feature-file-inherit-route-add/src/styles/global.css +14 -0
  345. package/test/e2e/gold/feature-file-prepend-append-apply/digitalExperiences/webApplications/feature-file-prepend-append/package.json +10 -0
  346. package/test/e2e/gold/feature-file-prepend-append-apply/digitalExperiences/webApplications/feature-file-prepend-append/src/appLayout.tsx +27 -0
  347. package/test/e2e/gold/feature-file-prepend-append-apply/digitalExperiences/webApplications/feature-file-prepend-append/src/home.tsx +8 -0
  348. package/test/e2e/gold/feature-file-prepend-append-apply/digitalExperiences/webApplications/feature-file-prepend-append/src/index.tsx +13 -0
  349. package/test/e2e/gold/feature-file-prepend-append-apply/digitalExperiences/webApplications/feature-file-prepend-append/src/old-page.tsx +8 -0
  350. package/test/e2e/gold/feature-file-prepend-append-apply/digitalExperiences/webApplications/feature-file-prepend-append/src/routes.tsx +29 -0
  351. package/test/e2e/gold/feature-file-prepend-append-apply/digitalExperiences/webApplications/feature-file-prepend-append/src/settings.tsx +9 -0
  352. package/test/e2e/gold/feature-file-prepend-append-apply/digitalExperiences/webApplications/feature-file-prepend-append/src/styles/global.css +25 -0
  353. package/test/e2e/gold/feature-file-route-delete-apply/digitalExperiences/webApplications/feature-file-route-delete/package.json +10 -0
  354. package/test/e2e/gold/feature-file-route-delete-apply/digitalExperiences/webApplications/feature-file-route-delete/src/appLayout.tsx +27 -0
  355. package/test/e2e/gold/feature-file-route-delete-apply/digitalExperiences/webApplications/feature-file-route-delete/src/home.tsx +8 -0
  356. package/test/e2e/gold/feature-file-route-delete-apply/digitalExperiences/webApplications/feature-file-route-delete/src/index.tsx +10 -0
  357. package/test/e2e/gold/feature-file-route-delete-apply/digitalExperiences/webApplications/feature-file-route-delete/src/routes.tsx +17 -0
  358. package/test/e2e/gold/feature-file-route-delete-apply/digitalExperiences/webApplications/feature-file-route-delete/src/styles/global.css +14 -0
  359. package/test/e2e/gold/feature-mixed-paths-apply/digitalExperiences/webApplications/feature-mixed-paths/assets/icon.svg +3 -0
  360. package/test/e2e/gold/feature-mixed-paths-apply/digitalExperiences/webApplications/feature-mixed-paths/package.json +10 -0
  361. package/test/e2e/gold/feature-mixed-paths-apply/digitalExperiences/webApplications/feature-mixed-paths/src/appLayout.tsx +27 -0
  362. package/test/e2e/gold/feature-mixed-paths-apply/digitalExperiences/webApplications/feature-mixed-paths/src/home.tsx +8 -0
  363. package/test/e2e/gold/feature-mixed-paths-apply/digitalExperiences/webApplications/feature-mixed-paths/src/index.tsx +10 -0
  364. package/test/e2e/gold/feature-mixed-paths-apply/digitalExperiences/webApplications/feature-mixed-paths/src/mapped-component.tsx +3 -0
  365. package/test/e2e/gold/feature-mixed-paths-apply/digitalExperiences/webApplications/feature-mixed-paths/src/old-page.tsx +8 -0
  366. package/test/e2e/gold/feature-mixed-paths-apply/digitalExperiences/webApplications/feature-mixed-paths/src/routes.tsx +28 -0
  367. package/test/e2e/gold/feature-mixed-paths-apply/digitalExperiences/webApplications/feature-mixed-paths/src/styles/global.css +14 -0
  368. package/test/e2e/gold/feature-with-webapp-mapping-apply/digitalExperiences/webApplications/feature-with-webapp-mapping/package.json +10 -0
  369. package/test/e2e/gold/feature-with-webapp-mapping-apply/digitalExperiences/webApplications/feature-with-webapp-mapping/src/app.tsx +3 -0
  370. package/test/e2e/gold/feature-with-webapp-mapping-apply/digitalExperiences/webApplications/feature-with-webapp-mapping/src/appLayout.tsx +27 -0
  371. package/test/e2e/gold/feature-with-webapp-mapping-apply/digitalExperiences/webApplications/feature-with-webapp-mapping/src/home.tsx +8 -0
  372. package/test/e2e/gold/feature-with-webapp-mapping-apply/digitalExperiences/webApplications/feature-with-webapp-mapping/src/index.tsx +10 -0
  373. package/test/e2e/gold/feature-with-webapp-mapping-apply/digitalExperiences/webApplications/feature-with-webapp-mapping/src/old-page.tsx +8 -0
  374. package/test/e2e/gold/feature-with-webapp-mapping-apply/digitalExperiences/webApplications/feature-with-webapp-mapping/src/routes.tsx +28 -0
  375. package/test/e2e/gold/feature-with-webapp-mapping-apply/digitalExperiences/webApplications/feature-with-webapp-mapping/src/styles/global.css +14 -0
  376. package/test/e2e/gold/feature-without-mapping-apply/digitalExperiences/webApplications/feature-without-mapping/package.json +10 -0
  377. package/test/e2e/gold/feature-without-mapping-apply/digitalExperiences/webApplications/feature-without-mapping/src/appLayout.tsx +27 -0
  378. package/test/e2e/gold/feature-without-mapping-apply/digitalExperiences/webApplications/feature-without-mapping/src/home.tsx +8 -0
  379. package/test/e2e/gold/feature-without-mapping-apply/digitalExperiences/webApplications/feature-without-mapping/src/index.tsx +10 -0
  380. package/test/e2e/gold/feature-without-mapping-apply/digitalExperiences/webApplications/feature-without-mapping/src/legacy-component.tsx +3 -0
  381. package/test/e2e/gold/feature-without-mapping-apply/digitalExperiences/webApplications/feature-without-mapping/src/old-page.tsx +8 -0
  382. package/test/e2e/gold/feature-without-mapping-apply/digitalExperiences/webApplications/feature-without-mapping/src/routes.tsx +28 -0
  383. package/test/e2e/gold/feature-without-mapping-apply/digitalExperiences/webApplications/feature-without-mapping/src/styles/global.css +14 -0
  384. package/test/e2e/path-mappings.spec.ts +232 -0
  385. package/test/e2e/watch-patches.spec.ts +237 -0
  386. package/test/helpers/cli-runner.ts +100 -0
  387. package/test/helpers/compare-directories.ts +197 -0
  388. package/test/helpers/create-temp-dir.ts +34 -0
  389. package/test/helpers/fixtures.ts +67 -0
  390. package/test/setup.ts +6 -0
  391. package/test/unit/debounce.spec.ts +159 -0
  392. package/test/unit/dependency-resolver.spec.ts +260 -0
  393. package/test/unit/file-operations.spec.ts +264 -0
  394. package/test/unit/import-merger.spec.ts +395 -0
  395. package/test/unit/index.spec.ts +158 -0
  396. package/test/unit/new-app.spec.ts +178 -0
  397. package/test/unit/new-feature.spec.ts +178 -0
  398. package/test/unit/package-json-merger.spec.ts +275 -0
  399. package/test/unit/patch-loader.spec.ts +238 -0
  400. package/test/unit/path-mappings.spec.ts +241 -0
  401. package/test/unit/paths.spec.ts +247 -0
  402. package/test/unit/route-merger.spec.ts +265 -0
  403. package/test/unit/validation.spec.ts +311 -0
  404. package/tsconfig.json +20 -0
  405. package/vitest.config.ts +18 -0
@@ -0,0 +1,166 @@
1
+ import { join } from 'path';
2
+ import * as logger from '../utils/logger.js';
3
+ import { getMonorepoRoot } from '../utils/paths.js';
4
+ import { cpSync, existsSync, readFileSync, renameSync, rmSync, statSync, writeFileSync } from 'fs';
5
+ import { validateAppOrFeatureName, ValidationError } from '../utils/validation.js';
6
+ /**
7
+ * Create a new app or feature from the base-reference-app or base-feature template
8
+ *
9
+ * @param appOrFeatureName - Name of the app or feature (without "app-" or "feature-" prefix)
10
+ */
11
+ export async function newAppOrFeatureCommand(appOrFeatureName, appOrFeatureType) {
12
+ let targetDir;
13
+ try {
14
+ logger.heading(`Creating new ${appOrFeatureType}: ${appOrFeatureName}`);
15
+ // Step 1: Validate feature name format
16
+ logger.info(`Validating ${appOrFeatureType} name...`);
17
+ validateAppOrFeatureName(appOrFeatureName);
18
+ // Step 2: Generate full feature name with prefix
19
+ const fullFeatureName = appOrFeatureName.startsWith(`${appOrFeatureType}-`)
20
+ ? appOrFeatureName
21
+ : `${appOrFeatureType}-${appOrFeatureName}`;
22
+ const rawName = fullFeatureName.replace(/^${appOrFeatureType}-/, '');
23
+ logger.success(`${appOrFeatureType} name validated: ${fullFeatureName}`);
24
+ // Step 3: Check if feature already exists
25
+ logger.info(`Checking if ${appOrFeatureType} already exists...`);
26
+ if (checkAppFeatureExists(fullFeatureName)) {
27
+ throw new ValidationError(`${appOrFeatureType} '${fullFeatureName}' already exists at packages/${fullFeatureName}.\nPlease choose a different name or remove the existing ${appOrFeatureType}.`);
28
+ }
29
+ logger.success('Feature name available');
30
+ // Step 4: Validate base feature template
31
+ logger.info('Validating base feature template...');
32
+ const baseAppOrFeaturePath = validateBaseAppOrFeature(appOrFeatureType);
33
+ logger.success('Base feature template validated');
34
+ // Step 5: Create target directory and copy
35
+ const monorepoRoot = getMonorepoRoot();
36
+ targetDir = join(monorepoRoot, 'packages', fullFeatureName);
37
+ logger.info(`Copying base feature template to packages/${fullFeatureName}...`);
38
+ cpSync(baseAppOrFeaturePath, targetDir, { recursive: true });
39
+ logger.success('Template copied');
40
+ // Step 6: Rename webApplications directory
41
+ logger.info('Renaming template directories...');
42
+ const templateName = appOrFeatureType === 'app' ? 'reference-app' : 'feature';
43
+ const oldWebAppPath = join(targetDir, `template/digitalExperiences/webApplications/base-${templateName}`);
44
+ const newWebAppPath = join(targetDir, 'template/digitalExperiences/webApplications', rawName);
45
+ if (existsSync(oldWebAppPath)) {
46
+ renameSync(oldWebAppPath, newWebAppPath);
47
+ logger.success(`Renamed: base-${templateName} → ${rawName}`);
48
+ }
49
+ // Step 7: Update package.json
50
+ logger.info('Updating package.json...');
51
+ const packageJsonPath = join(targetDir, 'package.json');
52
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
53
+ packageJson.name = fullFeatureName;
54
+ // Update scripts to reference new feature name
55
+ // Replace both "base-feature" and any existing "feature-*" patterns
56
+ const regexPattern = new RegExp(`base-${templateName}`, 'g');
57
+ if (packageJson.scripts) {
58
+ if (packageJson.scripts.dev) {
59
+ packageJson.scripts.dev = packageJson.scripts.dev
60
+ .replace(regexPattern, fullFeatureName);
61
+ }
62
+ if (packageJson.scripts['test-patch']) {
63
+ packageJson.scripts['test-patch'] = packageJson.scripts['test-patch']
64
+ .replace(regexPattern, fullFeatureName);
65
+ }
66
+ if (packageJson.scripts.watch) {
67
+ packageJson.scripts.watch = packageJson.scripts.watch
68
+ .replace(regexPattern, fullFeatureName);
69
+ }
70
+ }
71
+ writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n');
72
+ logger.success('package.json updated');
73
+ // Step 8: Update tsconfig.app.json
74
+ logger.info('Updating tsconfig.app.json...');
75
+ const tsconfigAppPath = join(targetDir, 'tsconfig.app.json');
76
+ let tsconfigContent = readFileSync(tsconfigAppPath, 'utf-8');
77
+ // Replace the include path (handles both single and array format)
78
+ // tsconfigContent = tsconfigContent.replace(
79
+ // /"include":\s*\[.*?\]/s,
80
+ // `"include": ["template/digitalExperiences/webApplications/${rawName}"]`
81
+ // );
82
+ writeFileSync(tsconfigAppPath, tsconfigContent);
83
+ logger.success('tsconfig.app.json updated');
84
+ // Step 9: Success message
85
+ logger.heading('\n✓ Success');
86
+ logger.success(`Created feature: packages/${fullFeatureName}`);
87
+ logger.info('\nNext steps:');
88
+ logger.info(` 1. cd packages/${fullFeatureName}`);
89
+ logger.info(' 2. Customize template files in template/ directory');
90
+ logger.info(` 3. Update feature.ts with ${appOrFeatureType} configuration`);
91
+ logger.info(` 4. Test with: yarn apply-patches packages/${fullFeatureName} packages/base-react-app test-app`);
92
+ }
93
+ catch (err) {
94
+ // Cleanup on failure
95
+ if (targetDir && existsSync(targetDir)) {
96
+ logger.info(`\nCleaning up partially created ${appOrFeatureType}...`);
97
+ rmSync(targetDir, { recursive: true, force: true });
98
+ logger.info('Cleanup complete');
99
+ }
100
+ // Handle different error types
101
+ if (err instanceof Error) {
102
+ // Handle permission errors
103
+ if (err.message.includes('EACCES')) {
104
+ logger.error(`\n✗ Permission denied. You do not have permission to create ${appOrFeatureType}s in the packages directory.`);
105
+ logger.info('Try running with appropriate permissions or check directory ownership.');
106
+ throw new ValidationError('Permission denied');
107
+ }
108
+ // Handle disk space errors
109
+ if (err.message.includes('ENOSPC')) {
110
+ logger.error(`\n✗ Not enough disk space to create ${appOrFeatureType}.`);
111
+ logger.info('Free up some disk space and try again.');
112
+ throw new ValidationError('Insufficient disk space');
113
+ }
114
+ }
115
+ // Log error if not already logged
116
+ const errorMessage = err instanceof Error ? err.message : String(err);
117
+ const skipLogging = err instanceof ValidationError;
118
+ if (!skipLogging) {
119
+ logger.error(`\n✗ Failed to create ${appOrFeatureType}: ${errorMessage}`);
120
+ }
121
+ else {
122
+ logger.error(`\n✗ ${errorMessage}`);
123
+ }
124
+ throw err;
125
+ }
126
+ }
127
+ /**
128
+ * Check if a feature already exists in the packages directory
129
+ */
130
+ function checkAppFeatureExists(appOrFeatureName) {
131
+ const monorepoRoot = getMonorepoRoot();
132
+ const appOrFeaturePath = join(monorepoRoot, 'packages', appOrFeatureName);
133
+ return existsSync(appOrFeaturePath);
134
+ }
135
+ /**
136
+ * Validate that the base-feature and base-reference-app template exists and is valid
137
+ * Returns the absolute path to the base-feature or base-reference-app directory
138
+ */
139
+ function validateBaseAppOrFeature(appOrFeatureType) {
140
+ const monorepoRoot = getMonorepoRoot();
141
+ const templateName = appOrFeatureType === 'app' ? 'reference-app' : 'feature';
142
+ const baseAppOrFeaturePath = join(monorepoRoot, `packages/base-${templateName}`);
143
+ if (!existsSync(baseAppOrFeaturePath)) {
144
+ throw new ValidationError(`Base ${templateName} template not found at packages/base-${templateName}.\nCannot create new ${appOrFeatureType}.`);
145
+ }
146
+ if (!statSync(baseAppOrFeaturePath).isDirectory()) {
147
+ throw new ValidationError(`Base ${templateName} template at packages/base-${templateName} is not a directory.`);
148
+ }
149
+ // Check critical files exist
150
+ const requiredFiles = [
151
+ 'package.json',
152
+ 'feature.ts',
153
+ 'tsconfig.app.json',
154
+ 'tsconfig.json',
155
+ 'tsconfig.node.json',
156
+ 'template'
157
+ ];
158
+ for (const file of requiredFiles) {
159
+ const filePath = join(baseAppOrFeaturePath, file);
160
+ if (!existsSync(filePath)) {
161
+ throw new ValidationError(`Base ${appOrFeatureType} template is incomplete.\nMissing required file: ${file}`);
162
+ }
163
+ }
164
+ return baseAppOrFeaturePath;
165
+ }
166
+ //# sourceMappingURL=new-app-feature.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"new-app-feature.js","sourceRoot":"","sources":["../../src/commands/new-app-feature.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=new-app.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"new-app.d.ts","sourceRoot":"","sources":["../../src/commands/new-app.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ //# sourceMappingURL=new-app.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"new-app.js","sourceRoot":"","sources":["../../src/commands/new-app.ts"],"names":[],"mappings":""}
@@ -0,0 +1,6 @@
1
+ export declare function watchPatchesCommand(featurePath: string, appPath: string, targetDirName: string, options?: {
2
+ clean?: boolean;
3
+ }): Promise<{
4
+ shutdown: () => Promise<void>;
5
+ }>;
6
+ //# sourceMappingURL=watch-patches.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watch-patches.d.ts","sourceRoot":"","sources":["../../src/commands/watch-patches.ts"],"names":[],"mappings":"AASA,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,aAAa,EAAE,MAAM,EACrB,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAChC,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC,CA8J5C"}
@@ -0,0 +1,152 @@
1
+ import { watch } from 'turbowatch';
2
+ import { join, relative, basename } from 'path';
3
+ import { existsSync, cpSync, rmSync } from 'fs';
4
+ import { applyPatchesCommand } from './apply-patches.js';
5
+ import { validateAndResolveFeaturePath, validateAndResolveAppPath } from '../utils/validation.js';
6
+ import { getMonorepoRoot, translatePathToBaseApp } from '../utils/paths.js';
7
+ import { loadFeature } from '../core/patch-loader.js';
8
+ import * as logger from '../utils/logger.js';
9
+ export async function watchPatchesCommand(featurePath, appPath, targetDirName, options = {}) {
10
+ try {
11
+ logger.heading(`Starting watch mode for ${featurePath}...`);
12
+ // Step 1: Validate inputs
13
+ logger.info('Validating feature and app path...');
14
+ const featureDir = validateAndResolveFeaturePath(featurePath);
15
+ validateAndResolveAppPath(appPath);
16
+ logger.success('Validation passed');
17
+ // Step 2: Apply feature initially (with dependencies)
18
+ logger.info('Applying feature initially...');
19
+ await applyPatchesCommand(featurePath, appPath, {
20
+ targetDirName: targetDirName,
21
+ skipDependencyChanges: false,
22
+ clean: options.clean
23
+ });
24
+ logger.success('Initial feature applied successfully\n');
25
+ // Step 3: Load feature config to get template directory
26
+ const { templateDir } = await loadFeature(featureDir);
27
+ const watchPath = join(featureDir, templateDir);
28
+ // Resolve base app and target directory paths
29
+ const baseAppPath = validateAndResolveAppPath(appPath);
30
+ const monorepoRoot = getMonorepoRoot();
31
+ const targetDir = targetDirName ? join(monorepoRoot, targetDirName) : baseAppPath;
32
+ logger.info(`👁 Watching ${watchPath} for changes...`);
33
+ logger.info(' Press Ctrl+C to stop watching\n');
34
+ // Create feature application function
35
+ const applyPatches = async (changedPath) => {
36
+ try {
37
+ const relativePath = changedPath.replace(watchPath + '/', '');
38
+ logger.info(`📝 Change detected in ${relativePath}`);
39
+ logger.info('⟳ Re-applying feature...\n');
40
+ const startTime = Date.now();
41
+ await applyPatchesCommand(featurePath, appPath, {
42
+ targetDirName: targetDirName,
43
+ skipDependencyChanges: true,
44
+ clean: options.clean
45
+ });
46
+ const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
47
+ logger.success(`\n✓ Feature re-applied successfully (${elapsed}s)`);
48
+ logger.info('👁 Watching for changes...\n');
49
+ }
50
+ catch (err) {
51
+ const errorMessage = err instanceof Error ? err.message : String(err);
52
+ // Only log if not already handled
53
+ const skipLogging = [
54
+ 'Path conflict - cannot proceed',
55
+ 'Delete validation failed - cannot proceed',
56
+ 'Inherit validation failed - cannot proceed',
57
+ 'Prepend validation failed - cannot proceed',
58
+ 'Append validation failed - cannot proceed',
59
+ 'Route deletion failed - cannot proceed'
60
+ ].includes(errorMessage);
61
+ if (!skipLogging) {
62
+ logger.error(`\n✗ Failed to apply feature: ${errorMessage}`);
63
+ }
64
+ logger.info(' Fix the issue and save again to retry');
65
+ logger.info('👁 Watching for changes...\n');
66
+ }
67
+ };
68
+ // Handle file deletion - restore base app file if it exists, otherwise delete
69
+ const handleDeletion = async (deletedPath) => {
70
+ try {
71
+ const relativePath = deletedPath.replace(watchPath + '/', '');
72
+ logger.info(`🗑 Deletion detected in ${relativePath}`);
73
+ // Calculate paths
74
+ const relativeFromFeature = relative(watchPath, deletedPath);
75
+ const featureName = basename(featurePath);
76
+ // Translate the path to the base app structure
77
+ const translatedPath = translatePathToBaseApp(relativeFromFeature, featureName, baseAppPath);
78
+ const targetFilePath = join(targetDir, translatedPath);
79
+ const baseFilePath = join(baseAppPath, translatedPath);
80
+ // Check if file exists in base app
81
+ if (existsSync(baseFilePath)) {
82
+ // Restore base app version
83
+ cpSync(baseFilePath, targetFilePath);
84
+ logger.success(`✓ Restored base app version of ${translatedPath}`);
85
+ }
86
+ else {
87
+ // No base version, delete from target
88
+ if (existsSync(targetFilePath)) {
89
+ rmSync(targetFilePath);
90
+ logger.success(`✓ Deleted ${translatedPath}`);
91
+ }
92
+ }
93
+ logger.info('👁 Watching for changes...\n');
94
+ }
95
+ catch (err) {
96
+ logger.error(`\n✗ Failed to handle deletion: ${err instanceof Error ? err.message : String(err)}`);
97
+ logger.info(' Will retry on next file change');
98
+ logger.info('👁 Watching for changes...\n');
99
+ }
100
+ };
101
+ // Set up turbowatch watcher
102
+ const controller = await watch({
103
+ project: watchPath,
104
+ debounce: {
105
+ wait: 500
106
+ },
107
+ triggers: [
108
+ {
109
+ expression: ['anyof', ['match', '*.tsx', 'basename'], ['match', '*.ts', 'basename'], ['match', '*.css', 'basename']],
110
+ name: 'source-files',
111
+ onChange: async ({ files }) => {
112
+ for (const file of files) {
113
+ // Check if file still exists to detect deletions
114
+ if (!existsSync(file.name)) {
115
+ await handleDeletion(file.name);
116
+ }
117
+ await applyPatches(file.name);
118
+ }
119
+ }
120
+ }
121
+ ]
122
+ });
123
+ // Handle graceful shutdown
124
+ const cleanup = async () => {
125
+ logger.info('\n🛑 Stopping watcher...');
126
+ await controller.shutdown();
127
+ logger.success('✓ Watch mode stopped');
128
+ process.exit(0);
129
+ };
130
+ process.on('SIGINT', cleanup);
131
+ process.on('SIGTERM', cleanup);
132
+ // Return controller for tests to use
133
+ return controller;
134
+ }
135
+ catch (err) {
136
+ // Only log error if it's not already been logged
137
+ const errorMessage = err instanceof Error ? err.message : String(err);
138
+ const skipLogging = [
139
+ 'Path conflict - cannot proceed',
140
+ 'Delete validation failed - cannot proceed',
141
+ 'Inherit validation failed - cannot proceed',
142
+ 'Prepend validation failed - cannot proceed',
143
+ 'Append validation failed - cannot proceed',
144
+ 'Route deletion failed - cannot proceed'
145
+ ].includes(errorMessage);
146
+ if (!skipLogging) {
147
+ logger.error(`\nWatch mode failed: ${errorMessage}`);
148
+ }
149
+ throw err;
150
+ }
151
+ }
152
+ //# sourceMappingURL=watch-patches.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watch-patches.js","sourceRoot":"","sources":["../../src/commands/watch-patches.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ import { type FeatureConfig } from './patch-loader.js';
2
+ /**
3
+ * Represents a resolved feature with its configuration
4
+ */
5
+ export type ResolvedFeature = {
6
+ featurePath: string;
7
+ featureDir: string;
8
+ config: FeatureConfig;
9
+ };
10
+ /**
11
+ * Result of dependency resolution
12
+ */
13
+ export type DependencyResolutionResult = {
14
+ orderedFeatures: ResolvedFeature[];
15
+ dependencyGraph: Map<string, string[]>;
16
+ };
17
+ /**
18
+ * Base error for dependency resolution failures
19
+ */
20
+ export declare class DependencyResolutionError extends Error {
21
+ constructor(message: string);
22
+ }
23
+ /**
24
+ * Error thrown when a circular dependency is detected
25
+ */
26
+ export declare class CircularDependencyError extends DependencyResolutionError {
27
+ cycle: string[];
28
+ constructor(cycle: string[]);
29
+ }
30
+ /**
31
+ * Resolve all dependencies for a feature recursively
32
+ * Returns features in dependency order (dependencies first, main feature last)
33
+ *
34
+ * @param featurePath - Path to the main feature
35
+ * @returns Resolution result with ordered features and dependency graph
36
+ * @throws CircularDependencyError if circular dependencies are detected
37
+ * @throws DependencyResolutionError if a dependency cannot be loaded
38
+ */
39
+ export declare function resolveDependencies(featurePath: string): Promise<DependencyResolutionResult>;
40
+ //# sourceMappingURL=dependency-resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependency-resolver.d.ts","sourceRoot":"","sources":["../../src/core/dependency-resolver.ts"],"names":[],"mappings":"AAEA,OAAO,EAAe,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGpE;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,aAAa,CAAC;CACvB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,0BAA0B,GAAG;IACvC,eAAe,EAAE,eAAe,EAAE,CAAC;IACnC,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CACxC,CAAC;AAEF;;GAEG;AACH,qBAAa,yBAA0B,SAAQ,KAAK;gBACtC,OAAO,EAAE,MAAM;CAI5B;AAED;;GAEG;AACH,qBAAa,uBAAwB,SAAQ,yBAAyB;IACjD,KAAK,EAAE,MAAM,EAAE;gBAAf,KAAK,EAAE,MAAM,EAAE;CAKnC;AAyFD;;;;;;;;GAQG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,0BAA0B,CAAC,CAiCrC"}
@@ -0,0 +1,122 @@
1
+ import { join, isAbsolute } from 'path';
2
+ import { validateAndResolveFeaturePath } from '../utils/validation.js';
3
+ import { loadFeature } from './patch-loader.js';
4
+ import { getMonorepoRoot } from '../utils/paths.js';
5
+ /**
6
+ * Base error for dependency resolution failures
7
+ */
8
+ export class DependencyResolutionError extends Error {
9
+ constructor(message) {
10
+ super(message);
11
+ this.name = 'DependencyResolutionError';
12
+ }
13
+ }
14
+ /**
15
+ * Error thrown when a circular dependency is detected
16
+ */
17
+ export class CircularDependencyError extends DependencyResolutionError {
18
+ cycle;
19
+ constructor(cycle) {
20
+ const cycleStr = cycle.join(' → ');
21
+ super(`Circular dependency detected:\n ${cycleStr}\n\nPlease remove one of these dependencies to break the cycle.`);
22
+ this.cycle = cycle;
23
+ this.name = 'CircularDependencyError';
24
+ }
25
+ }
26
+ /**
27
+ * Normalize a feature path to an absolute path for consistent comparison
28
+ *
29
+ * @param featurePath - Relative or absolute feature path
30
+ * @returns Absolute path to the feature
31
+ */
32
+ function normalizePath(featurePath) {
33
+ // If already absolute, return as-is
34
+ if (isAbsolute(featurePath)) {
35
+ return featurePath;
36
+ }
37
+ // If relative, resolve from monorepo root
38
+ return join(getMonorepoRoot(), featurePath);
39
+ }
40
+ /**
41
+ * Recursively resolve dependencies using depth-first search with post-order traversal
42
+ *
43
+ * @param featurePath - Path to the feature to resolve
44
+ * @param visited - Set of features currently being processed (for cycle detection)
45
+ * @param resolved - Set of features that have been fully processed
46
+ * @param result - Accumulator for ordered features
47
+ * @param dependencyGraph - Map of feature paths to their dependencies
48
+ * @param dependencyChain - Current chain of dependencies (for error messages)
49
+ */
50
+ async function resolveDependenciesRecursive(featurePath, visited, resolved, result, dependencyGraph, dependencyChain) {
51
+ const normalizedPath = normalizePath(featurePath);
52
+ // Skip if already resolved (handles diamond dependencies)
53
+ if (resolved.has(normalizedPath)) {
54
+ return;
55
+ }
56
+ // Circular dependency detection
57
+ if (visited.has(normalizedPath)) {
58
+ const cycle = [...dependencyChain, featurePath];
59
+ throw new CircularDependencyError(cycle);
60
+ }
61
+ // Mark as visiting
62
+ visited.add(normalizedPath);
63
+ dependencyChain.push(featurePath);
64
+ try {
65
+ // Validate and load feature
66
+ const featureDir = validateAndResolveFeaturePath(featurePath);
67
+ const config = await loadFeature(featureDir);
68
+ // Store in dependency graph for debugging
69
+ dependencyGraph.set(normalizedPath, config.dependencies);
70
+ // Recursively resolve dependencies (depth-first)
71
+ for (const depPath of config.dependencies) {
72
+ await resolveDependenciesRecursive(depPath, visited, resolved, result, dependencyGraph, [...dependencyChain] // Pass copy for independent error messages
73
+ );
74
+ }
75
+ // Post-order: add after all dependencies are resolved
76
+ result.push({
77
+ featurePath,
78
+ featureDir,
79
+ config
80
+ });
81
+ // Mark as resolved
82
+ resolved.add(normalizedPath);
83
+ }
84
+ finally {
85
+ // Clean up visiting state
86
+ visited.delete(normalizedPath);
87
+ dependencyChain.pop();
88
+ }
89
+ }
90
+ /**
91
+ * Resolve all dependencies for a feature recursively
92
+ * Returns features in dependency order (dependencies first, main feature last)
93
+ *
94
+ * @param featurePath - Path to the main feature
95
+ * @returns Resolution result with ordered features and dependency graph
96
+ * @throws CircularDependencyError if circular dependencies are detected
97
+ * @throws DependencyResolutionError if a dependency cannot be loaded
98
+ */
99
+ export async function resolveDependencies(featurePath) {
100
+ const visited = new Set();
101
+ const resolved = new Set();
102
+ const result = [];
103
+ const dependencyGraph = new Map();
104
+ const dependencyChain = [];
105
+ try {
106
+ await resolveDependenciesRecursive(featurePath, visited, resolved, result, dependencyGraph, dependencyChain);
107
+ return {
108
+ orderedFeatures: result,
109
+ dependencyGraph
110
+ };
111
+ }
112
+ catch (err) {
113
+ // Re-throw our custom errors as-is
114
+ if (err instanceof DependencyResolutionError) {
115
+ throw err;
116
+ }
117
+ // Wrap other errors
118
+ const message = err instanceof Error ? err.message : String(err);
119
+ throw new DependencyResolutionError(`Failed to resolve dependencies: ${message}`);
120
+ }
121
+ }
122
+ //# sourceMappingURL=dependency-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependency-resolver.js","sourceRoot":"","sources":["../../src/core/dependency-resolver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ export declare class FileOperationError extends Error {
2
+ constructor(message: string);
3
+ }
4
+ /**
5
+ * Apply a file from patch to target, optionally merging with base
6
+ *
7
+ * @param patchFilePath - Full path to the patch file from the feature
8
+ * @param baseFilePath - Full path to the original base app file (used for merging)
9
+ * @param targetFilePath - Full path to where the result should be written
10
+ * @param relativeTargetPath - Relative path for logging (e.g. "src/routes.tsx")
11
+ * @param shouldMerge - If true, merges patch with base using route merge strategy
12
+ */
13
+ export declare function applyFile(patchFilePath: string, baseFilePath: string, targetFilePath: string, relativeTargetPath: string, shouldMerge?: boolean): Promise<void>;
14
+ /**
15
+ * Delete a file or directory from the target app
16
+ *
17
+ * @param targetFilePath - Full path to the file/directory to delete
18
+ * @param relativeTargetPath - Relative path for logging (e.g. "src/routes.tsx")
19
+ */
20
+ export declare function deleteFile(targetFilePath: string, relativeTargetPath: string): Promise<void>;
21
+ /**
22
+ * Prepend content from a feature file to the beginning of a target file
23
+ *
24
+ * @param featureFilePath - Full path to the feature file with content to prepend
25
+ * @param targetFilePath - Full path to the target file to prepend to
26
+ * @param relativeTargetPath - Relative path for logging (e.g. "src/styles/global.css")
27
+ */
28
+ export declare function prependToFile(featureFilePath: string, targetFilePath: string, relativeTargetPath: string): Promise<void>;
29
+ /**
30
+ * Append content from a feature file to the end of a target file
31
+ *
32
+ * @param featureFilePath - Full path to the feature file with content to append
33
+ * @param targetFilePath - Full path to the target file to append to
34
+ * @param relativeTargetPath - Relative path for logging (e.g. "src/styles/global.css")
35
+ */
36
+ export declare function appendToFile(featureFilePath: string, targetFilePath: string, relativeTargetPath: string): Promise<void>;
37
+ //# sourceMappingURL=file-operations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-operations.d.ts","sourceRoot":"","sources":["../../src/core/file-operations.ts"],"names":[],"mappings":"AAOA,qBAAa,kBAAmB,SAAQ,KAAK;gBAC/B,OAAO,EAAE,MAAM;CAI5B;AA4CD;;;;;;;;GAQG;AACH,wBAAsB,SAAS,CAC7B,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,MAAM,EACpB,cAAc,EAAE,MAAM,EACtB,kBAAkB,EAAE,MAAM,EAC1B,WAAW,GAAE,OAAe,GAC3B,OAAO,CAAC,IAAI,CAAC,CA2Ef;AAED;;;;;GAKG;AACH,wBAAsB,UAAU,CAC9B,cAAc,EAAE,MAAM,EACtB,kBAAkB,EAAE,MAAM,GACzB,OAAO,CAAC,IAAI,CAAC,CAef;AAED;;;;;;GAMG;AACH,wBAAsB,aAAa,CACjC,eAAe,EAAE,MAAM,EACvB,cAAc,EAAE,MAAM,EACtB,kBAAkB,EAAE,MAAM,GACzB,OAAO,CAAC,IAAI,CAAC,CAiCf;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAChC,eAAe,EAAE,MAAM,EACvB,cAAc,EAAE,MAAM,EACtB,kBAAkB,EAAE,MAAM,GACzB,OAAO,CAAC,IAAI,CAAC,CAiCf"}