n8n 2.7.3 → 2.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (312) hide show
  1. package/dist/active-workflow-manager.js +0 -1
  2. package/dist/active-workflow-manager.js.map +1 -1
  3. package/dist/auth/auth-handler.registry.d.ts +15 -0
  4. package/dist/auth/auth-handler.registry.js +87 -0
  5. package/dist/auth/auth-handler.registry.js.map +1 -0
  6. package/dist/auth/handlers/email.auth-handler.d.ts +19 -0
  7. package/dist/auth/handlers/email.auth-handler.js +52 -0
  8. package/dist/auth/handlers/email.auth-handler.js.map +1 -0
  9. package/dist/build.tsbuildinfo +1 -1
  10. package/dist/chat/chat-service.types.d.ts +2 -2
  11. package/dist/commands/base-command.js +5 -2
  12. package/dist/commands/base-command.js.map +1 -1
  13. package/dist/commands/start.js +17 -0
  14. package/dist/commands/start.js.map +1 -1
  15. package/dist/controllers/ai.controller.js +2 -0
  16. package/dist/controllers/ai.controller.js.map +1 -1
  17. package/dist/controllers/auth.controller.d.ts +8 -1
  18. package/dist/controllers/auth.controller.js +66 -85
  19. package/dist/controllers/auth.controller.js.map +1 -1
  20. package/dist/controllers/dynamic-node-parameters.controller.d.ts +2 -2
  21. package/dist/controllers/dynamic-node-parameters.controller.js +13 -13
  22. package/dist/controllers/dynamic-node-parameters.controller.js.map +1 -1
  23. package/dist/controllers/e2e.controller.d.ts +4 -0
  24. package/dist/controllers/e2e.controller.js +18 -0
  25. package/dist/controllers/e2e.controller.js.map +1 -1
  26. package/dist/controllers/me.controller.d.ts +2 -2
  27. package/dist/controllers/me.controller.js +1 -1
  28. package/dist/controllers/me.controller.js.map +1 -1
  29. package/dist/controllers/mfa.controller.js +11 -0
  30. package/dist/controllers/mfa.controller.js.map +1 -1
  31. package/dist/controllers/security-settings.controller.d.ts +18 -0
  32. package/dist/controllers/security-settings.controller.js +96 -0
  33. package/dist/controllers/security-settings.controller.js.map +1 -0
  34. package/dist/controllers/users.controller.js.map +1 -1
  35. package/dist/credentials/credentials-finder.service.d.ts +1 -5
  36. package/dist/credentials/credentials-finder.service.js +2 -2
  37. package/dist/credentials/credentials-finder.service.js.map +1 -1
  38. package/dist/eventbus/event-message-classes/event-message-audit.d.ts +4 -0
  39. package/dist/eventbus/event-message-classes/event-message-audit.js.map +1 -1
  40. package/dist/eventbus/event-message-classes/index.d.ts +2 -2
  41. package/dist/eventbus/event-message-classes/index.js +7 -0
  42. package/dist/eventbus/event-message-classes/index.js.map +1 -1
  43. package/dist/events/maps/relay.event-map.d.ts +14 -0
  44. package/dist/events/relays/log-streaming.event-relay.d.ts +2 -0
  45. package/dist/events/relays/log-streaming.event-relay.js +60 -2
  46. package/dist/events/relays/log-streaming.event-relay.js.map +1 -1
  47. package/dist/events/relays/telemetry.event-relay.d.ts +1 -0
  48. package/dist/events/relays/telemetry.event-relay.js +7 -0
  49. package/dist/events/relays/telemetry.event-relay.js.map +1 -1
  50. package/dist/execution-lifecycle/execution-lifecycle-hooks.js +14 -0
  51. package/dist/execution-lifecycle/execution-lifecycle-hooks.js.map +1 -1
  52. package/dist/modules/chat-hub/chat-hub-execution-store.service.d.ts +44 -0
  53. package/dist/modules/chat-hub/chat-hub-execution-store.service.js +159 -0
  54. package/dist/modules/chat-hub/chat-hub-execution-store.service.js.map +1 -0
  55. package/dist/modules/chat-hub/chat-hub-execution-watcher.service.d.ts +25 -0
  56. package/dist/modules/chat-hub/chat-hub-execution-watcher.service.js +205 -0
  57. package/dist/modules/chat-hub/chat-hub-execution-watcher.service.js.map +1 -0
  58. package/dist/modules/chat-hub/chat-hub-execution.service.d.ts +10 -12
  59. package/dist/modules/chat-hub/chat-hub-execution.service.js +93 -187
  60. package/dist/modules/chat-hub/chat-hub-execution.service.js.map +1 -1
  61. package/dist/modules/chat-hub/chat-hub-title.service.js +2 -2
  62. package/dist/modules/chat-hub/chat-hub-title.service.js.map +1 -1
  63. package/dist/modules/chat-hub/chat-hub-workflow.service.d.ts +1 -0
  64. package/dist/modules/chat-hub/chat-hub-workflow.service.js +101 -9
  65. package/dist/modules/chat-hub/chat-hub-workflow.service.js.map +1 -1
  66. package/dist/modules/chat-hub/chat-hub.constants.js +7 -3
  67. package/dist/modules/chat-hub/chat-hub.constants.js.map +1 -1
  68. package/dist/modules/chat-hub/chat-hub.models.service.d.ts +2 -2
  69. package/dist/modules/chat-hub/chat-hub.models.service.js.map +1 -1
  70. package/dist/modules/chat-hub/chat-hub.module.js +7 -0
  71. package/dist/modules/chat-hub/chat-hub.module.js.map +1 -1
  72. package/dist/modules/chat-hub/chat-hub.service.js +3 -6
  73. package/dist/modules/chat-hub/chat-hub.service.js.map +1 -1
  74. package/dist/modules/chat-hub/chat-stream-state.service.d.ts +4 -2
  75. package/dist/modules/chat-hub/chat-stream-state.service.js +11 -11
  76. package/dist/modules/chat-hub/chat-stream-state.service.js.map +1 -1
  77. package/dist/modules/chat-hub/chat-stream.service.d.ts +1 -1
  78. package/dist/modules/chat-hub/chat-stream.service.js +1 -1
  79. package/dist/modules/chat-hub/chat-stream.service.js.map +1 -1
  80. package/dist/modules/chat-hub/dto/chat-models-request.dto.d.ts +3 -2
  81. package/dist/modules/chat-hub/dto/chat-models-request.dto.js +1 -2
  82. package/dist/modules/chat-hub/dto/chat-models-request.dto.js.map +1 -1
  83. package/dist/modules/community-packages/community-node-types.service.d.ts +1 -0
  84. package/dist/modules/community-packages/community-node-types.service.js +30 -0
  85. package/dist/modules/community-packages/community-node-types.service.js.map +1 -1
  86. package/dist/modules/data-table/data-table.controller.d.ts +4 -1
  87. package/dist/modules/data-table/data-table.controller.js +23 -2
  88. package/dist/modules/data-table/data-table.controller.js.map +1 -1
  89. package/dist/modules/data-table/middleware/branch-write-access-middleware.d.ts +2 -0
  90. package/dist/modules/data-table/middleware/branch-write-access-middleware.js +15 -0
  91. package/dist/modules/data-table/middleware/branch-write-access-middleware.js.map +1 -0
  92. package/dist/modules/dynamic-credentials.ee/credential-resolvers/identifiers/oauth2-introspection-identifier.d.ts +2 -2
  93. package/dist/modules/dynamic-credentials.ee/services/dynamic-credential-web.service.js +2 -2
  94. package/dist/modules/dynamic-credentials.ee/services/dynamic-credential-web.service.js.map +1 -1
  95. package/dist/modules/external-secrets.ee/external-secrets-manager.ee.d.ts +16 -7
  96. package/dist/modules/external-secrets.ee/external-secrets-manager.ee.js +63 -20
  97. package/dist/modules/external-secrets.ee/external-secrets-manager.ee.js.map +1 -1
  98. package/dist/modules/external-secrets.ee/external-secrets-providers.ee.d.ts +2 -0
  99. package/dist/modules/external-secrets.ee/external-secrets-providers.ee.js +8 -0
  100. package/dist/modules/external-secrets.ee/external-secrets-providers.ee.js.map +1 -1
  101. package/dist/modules/external-secrets.ee/external-secrets.controller.ee.d.ts +7 -3
  102. package/dist/modules/external-secrets.ee/external-secrets.module.js +1 -1
  103. package/dist/modules/external-secrets.ee/external-secrets.module.js.map +1 -1
  104. package/dist/modules/external-secrets.ee/external-secrets.service.ee.d.ts +10 -5
  105. package/dist/modules/external-secrets.ee/external-secrets.service.ee.js +7 -45
  106. package/dist/modules/external-secrets.ee/external-secrets.service.ee.js.map +1 -1
  107. package/dist/modules/external-secrets.ee/redaction.service.ee.d.ts +7 -0
  108. package/dist/modules/external-secrets.ee/redaction.service.ee.js +56 -0
  109. package/dist/modules/external-secrets.ee/redaction.service.ee.js.map +1 -0
  110. package/dist/modules/external-secrets.ee/secrets-providers-completions.controller.ee.d.ts +15 -0
  111. package/dist/modules/external-secrets.ee/secrets-providers-completions.controller.ee.js +76 -0
  112. package/dist/modules/external-secrets.ee/secrets-providers-completions.controller.ee.js.map +1 -0
  113. package/dist/modules/external-secrets.ee/secrets-providers-connections.controller.ee.d.ts +10 -12
  114. package/dist/modules/external-secrets.ee/secrets-providers-connections.controller.ee.js +21 -42
  115. package/dist/modules/external-secrets.ee/secrets-providers-connections.controller.ee.js.map +1 -1
  116. package/dist/modules/external-secrets.ee/secrets-providers-connections.service.ee.d.ts +16 -3
  117. package/dist/modules/external-secrets.ee/secrets-providers-connections.service.ee.js +60 -5
  118. package/dist/modules/external-secrets.ee/secrets-providers-connections.service.ee.js.map +1 -1
  119. package/dist/modules/external-secrets.ee/secrets-providers-project.controller.ee.d.ts +8 -4
  120. package/dist/modules/external-secrets.ee/secrets-providers-project.controller.ee.js +20 -9
  121. package/dist/modules/external-secrets.ee/secrets-providers-project.controller.ee.js.map +1 -1
  122. package/dist/modules/external-secrets.ee/secrets-providers-types.controller.ee.d.ts +9 -5
  123. package/dist/modules/external-secrets.ee/secrets-providers-types.controller.ee.js +33 -13
  124. package/dist/modules/external-secrets.ee/secrets-providers-types.controller.ee.js.map +1 -1
  125. package/dist/modules/external-secrets.ee/secrets-providers.responses.ee.d.ts +9 -3
  126. package/dist/modules/insights/database/repositories/insights-by-period.repository.d.ts +3 -3
  127. package/dist/modules/insights/insights.service.d.ts +3 -3
  128. package/dist/modules/ldap.ee/ldap.module.js +1 -4
  129. package/dist/modules/ldap.ee/ldap.module.js.map +1 -1
  130. package/dist/modules/ldap.ee/ldap.service.ee.d.ts +11 -4
  131. package/dist/modules/ldap.ee/ldap.service.ee.js +5 -2
  132. package/dist/modules/ldap.ee/ldap.service.ee.js.map +1 -1
  133. package/dist/modules/log-streaming.ee/destinations/message-event-bus-destination-syslog.ee.js +1 -1
  134. package/dist/modules/log-streaming.ee/destinations/message-event-bus-destination-syslog.ee.js.map +1 -1
  135. package/dist/modules/log-streaming.ee/destinations/message-event-bus-destination-webhook.ee.js +10 -1
  136. package/dist/modules/log-streaming.ee/destinations/message-event-bus-destination-webhook.ee.js.map +1 -1
  137. package/dist/modules/mcp/dto/approve-consent-request.dto.d.ts +3 -2
  138. package/dist/modules/mcp/dto/approve-consent-request.dto.js +2 -2
  139. package/dist/modules/mcp/dto/approve-consent-request.dto.js.map +1 -1
  140. package/dist/modules/mcp/dto/update-mcp-settings.dto.d.ts +3 -2
  141. package/dist/modules/mcp/dto/update-mcp-settings.dto.js +2 -2
  142. package/dist/modules/mcp/dto/update-mcp-settings.dto.js.map +1 -1
  143. package/dist/modules/mcp/dto/update-workflow-availability.dto.d.ts +3 -2
  144. package/dist/modules/mcp/dto/update-workflow-availability.dto.js +2 -2
  145. package/dist/modules/mcp/dto/update-workflow-availability.dto.js.map +1 -1
  146. package/dist/modules/mcp/mcp.service.d.ts +15 -2
  147. package/dist/modules/mcp/mcp.service.js +66 -3
  148. package/dist/modules/mcp/mcp.service.js.map +1 -1
  149. package/dist/modules/mcp/tools/execute-workflow.tool.d.ts +3 -2
  150. package/dist/modules/mcp/tools/execute-workflow.tool.js +18 -9
  151. package/dist/modules/mcp/tools/execute-workflow.tool.js.map +1 -1
  152. package/dist/modules/mcp/tools/get-workflow-details.tool.js.map +1 -1
  153. package/dist/modules/mcp/tools/search-workflows.tool.js +1 -1
  154. package/dist/modules/mcp/tools/search-workflows.tool.js.map +1 -1
  155. package/dist/modules/quick-connect/handlers/quick-connect.handler.d.ts +11 -0
  156. package/dist/modules/quick-connect/handlers/quick-connect.handler.js +26 -0
  157. package/dist/modules/quick-connect/handlers/quick-connect.handler.js.map +1 -0
  158. package/dist/modules/quick-connect/handlers/sample.handler.d.ts +7 -0
  159. package/dist/modules/quick-connect/handlers/sample.handler.js +27 -0
  160. package/dist/modules/quick-connect/handlers/sample.handler.js.map +1 -0
  161. package/dist/modules/quick-connect/quick-connect.config.d.ts +95 -0
  162. package/dist/modules/quick-connect/quick-connect.config.js +48 -0
  163. package/dist/modules/quick-connect/quick-connect.config.js.map +1 -0
  164. package/dist/modules/quick-connect/quick-connect.controller.d.ts +10 -0
  165. package/dist/modules/quick-connect/quick-connect.controller.js +39 -0
  166. package/dist/modules/quick-connect/quick-connect.controller.js.map +1 -0
  167. package/dist/modules/quick-connect/quick-connect.errors.d.ts +5 -0
  168. package/dist/modules/quick-connect/quick-connect.errors.js +12 -0
  169. package/dist/modules/quick-connect/quick-connect.errors.js.map +1 -0
  170. package/dist/modules/quick-connect/quick-connect.module.d.ts +15 -0
  171. package/dist/modules/quick-connect/quick-connect.module.js +70 -0
  172. package/dist/modules/quick-connect/quick-connect.module.js.map +1 -0
  173. package/dist/modules/quick-connect/quick-connect.service.d.ts +17 -0
  174. package/dist/modules/quick-connect/quick-connect.service.js +87 -0
  175. package/dist/modules/quick-connect/quick-connect.service.js.map +1 -0
  176. package/dist/modules/source-control.ee/constants.d.ts +2 -0
  177. package/dist/modules/source-control.ee/constants.js +3 -1
  178. package/dist/modules/source-control.ee/constants.js.map +1 -1
  179. package/dist/modules/source-control.ee/source-control-export.service.ee.d.ts +6 -1
  180. package/dist/modules/source-control.ee/source-control-export.service.ee.js +136 -19
  181. package/dist/modules/source-control.ee/source-control-export.service.ee.js.map +1 -1
  182. package/dist/modules/source-control.ee/source-control-helper.ee.d.ts +10 -2
  183. package/dist/modules/source-control.ee/source-control-helper.ee.js +81 -5
  184. package/dist/modules/source-control.ee/source-control-helper.ee.js.map +1 -1
  185. package/dist/modules/source-control.ee/source-control-import.service.ee.d.ts +15 -1
  186. package/dist/modules/source-control.ee/source-control-import.service.ee.js +209 -3
  187. package/dist/modules/source-control.ee/source-control-import.service.ee.js.map +1 -1
  188. package/dist/modules/source-control.ee/source-control-scoped.service.d.ts +2 -0
  189. package/dist/modules/source-control.ee/source-control-scoped.service.js +8 -0
  190. package/dist/modules/source-control.ee/source-control-scoped.service.js.map +1 -1
  191. package/dist/modules/source-control.ee/source-control-status.service.ee.d.ts +3 -0
  192. package/dist/modules/source-control.ee/source-control-status.service.ee.js +494 -328
  193. package/dist/modules/source-control.ee/source-control-status.service.ee.js.map +1 -1
  194. package/dist/modules/source-control.ee/source-control.controller.ee.d.ts +2 -2
  195. package/dist/modules/source-control.ee/source-control.service.ee.d.ts +1 -1
  196. package/dist/modules/source-control.ee/source-control.service.ee.js +12 -1
  197. package/dist/modules/source-control.ee/source-control.service.ee.js.map +1 -1
  198. package/dist/modules/source-control.ee/types/exportable-data-table.d.ts +20 -0
  199. package/dist/modules/source-control.ee/types/exportable-data-table.js +3 -0
  200. package/dist/modules/source-control.ee/types/exportable-data-table.js.map +1 -0
  201. package/dist/modules/source-control.ee/types/source-control-get-status.d.ts +4 -0
  202. package/dist/modules/source-control.ee/types/source-control-get-status.js.map +1 -1
  203. package/dist/modules/sso-oidc/oidc.service.ee.js +7 -4
  204. package/dist/modules/sso-oidc/oidc.service.ee.js.map +1 -1
  205. package/dist/modules/sso-saml/saml.controller.ee.d.ts +10 -3
  206. package/dist/modules/workflow-index/workflow-index.service.d.ts +4 -2
  207. package/dist/modules/workflow-index/workflow-index.service.js +56 -29
  208. package/dist/modules/workflow-index/workflow-index.service.js.map +1 -1
  209. package/dist/oauth/oauth.service.js +9 -3
  210. package/dist/oauth/oauth.service.js.map +1 -1
  211. package/dist/public-api/types.d.ts +5 -0
  212. package/dist/public-api/v1/handlers/credentials/credentials.handler.d.ts +15 -0
  213. package/dist/public-api/v1/handlers/credentials/credentials.handler.js +37 -0
  214. package/dist/public-api/v1/handlers/credentials/credentials.handler.js.map +1 -1
  215. package/dist/public-api/v1/handlers/credentials/credentials.service.d.ts +8 -0
  216. package/dist/public-api/v1/handlers/credentials/credentials.service.js +13 -0
  217. package/dist/public-api/v1/handlers/credentials/credentials.service.js.map +1 -1
  218. package/dist/public-api/v1/handlers/projects/projects.handler.d.ts +4 -0
  219. package/dist/public-api/v1/handlers/projects/projects.handler.js +57 -0
  220. package/dist/public-api/v1/handlers/projects/projects.handler.js.map +1 -1
  221. package/dist/public-api/v1/handlers/workflows/workflows.handler.js +15 -15
  222. package/dist/public-api/v1/handlers/workflows/workflows.handler.js.map +1 -1
  223. package/dist/public-api/v1/openapi.yml +185 -31
  224. package/dist/push/abstract.push.js +2 -0
  225. package/dist/push/abstract.push.js.map +1 -1
  226. package/dist/scaling/constants.d.ts +1 -0
  227. package/dist/scaling/constants.js +2 -1
  228. package/dist/scaling/constants.js.map +1 -1
  229. package/dist/scaling/job-processor.d.ts +1 -0
  230. package/dist/scaling/job-processor.js +106 -0
  231. package/dist/scaling/job-processor.js.map +1 -1
  232. package/dist/scaling/pubsub/publisher.service.d.ts +4 -0
  233. package/dist/scaling/pubsub/publisher.service.js +14 -0
  234. package/dist/scaling/pubsub/publisher.service.js.map +1 -1
  235. package/dist/scaling/pubsub/subscriber.service.d.ts +10 -0
  236. package/dist/scaling/pubsub/subscriber.service.js +25 -0
  237. package/dist/scaling/pubsub/subscriber.service.js.map +1 -1
  238. package/dist/scaling/scaling.service.d.ts +1 -0
  239. package/dist/scaling/scaling.service.js +54 -0
  240. package/dist/scaling/scaling.service.js.map +1 -1
  241. package/dist/scaling/scaling.types.d.ts +20 -1
  242. package/dist/server.d.ts +1 -0
  243. package/dist/server.js +1 -0
  244. package/dist/server.js.map +1 -1
  245. package/dist/services/dynamic-node-parameters.service.d.ts +5 -3
  246. package/dist/services/dynamic-node-parameters.service.js +20 -3
  247. package/dist/services/dynamic-node-parameters.service.js.map +1 -1
  248. package/dist/services/folder.service.js +1 -1
  249. package/dist/services/folder.service.js.map +1 -1
  250. package/dist/services/frontend.service.d.ts +1 -0
  251. package/dist/services/frontend.service.js +9 -2
  252. package/dist/services/frontend.service.js.map +1 -1
  253. package/dist/services/rate-limit.service.d.ts +1 -1
  254. package/dist/services/rate-limit.service.js +1 -1
  255. package/dist/services/rate-limit.service.js.map +1 -1
  256. package/dist/services/role.service.d.ts +6 -3
  257. package/dist/services/role.service.js +39 -2
  258. package/dist/services/role.service.js.map +1 -1
  259. package/dist/services/security-settings.service.d.ts +20 -0
  260. package/dist/services/security-settings.service.js +68 -0
  261. package/dist/services/security-settings.service.js.map +1 -0
  262. package/dist/task-runners/task-broker/task-broker-ws-server.d.ts +4 -2
  263. package/dist/task-runners/task-broker/task-broker-ws-server.js +24 -2
  264. package/dist/task-runners/task-broker/task-broker-ws-server.js.map +1 -1
  265. package/dist/task-runners/task-broker/task-broker.service.d.ts +4 -0
  266. package/dist/task-runners/task-broker/task-broker.service.js +19 -0
  267. package/dist/task-runners/task-broker/task-broker.service.js.map +1 -1
  268. package/dist/telemetry/index.js +3 -0
  269. package/dist/telemetry/index.js.map +1 -1
  270. package/dist/webhooks/live-webhooks.js +2 -3
  271. package/dist/webhooks/live-webhooks.js.map +1 -1
  272. package/dist/webhooks/webhook-helpers.js +66 -7
  273. package/dist/webhooks/webhook-helpers.js.map +1 -1
  274. package/dist/workflow-runner.js +8 -2
  275. package/dist/workflow-runner.js.map +1 -1
  276. package/dist/workflows/workflow-finder.service.d.ts +2 -0
  277. package/dist/workflows/workflow-finder.service.js +22 -2
  278. package/dist/workflows/workflow-finder.service.js.map +1 -1
  279. package/dist/workflows/workflow-history/workflow-history-manager.d.ts +3 -1
  280. package/dist/workflows/workflow-history/workflow-history-manager.js +7 -3
  281. package/dist/workflows/workflow-history/workflow-history-manager.js.map +1 -1
  282. package/dist/workflows/workflow-history/workflow-history.controller.d.ts +6 -1
  283. package/dist/workflows/workflow-history/workflow-history.controller.js +24 -0
  284. package/dist/workflows/workflow-history/workflow-history.controller.js.map +1 -1
  285. package/dist/workflows/workflow-history/workflow-history.service.d.ts +7 -3
  286. package/dist/workflows/workflow-history/workflow-history.service.js +41 -4
  287. package/dist/workflows/workflow-history/workflow-history.service.js.map +1 -1
  288. package/dist/workflows/workflow-sharing.service.d.ts +1 -1
  289. package/dist/workflows/workflow-sharing.service.js +2 -2
  290. package/dist/workflows/workflow-sharing.service.js.map +1 -1
  291. package/dist/workflows/workflow-validation.service.d.ts +4 -2
  292. package/dist/workflows/workflow-validation.service.js +93 -1
  293. package/dist/workflows/workflow-validation.service.js.map +1 -1
  294. package/dist/workflows/workflow.service.d.ts +13 -6
  295. package/dist/workflows/workflow.service.ee.js +11 -4
  296. package/dist/workflows/workflow.service.ee.js.map +1 -1
  297. package/dist/workflows/workflow.service.js +70 -47
  298. package/dist/workflows/workflow.service.js.map +1 -1
  299. package/dist/workflows/workflows.controller.d.ts +3 -3
  300. package/dist/workflows/workflows.controller.js +16 -8
  301. package/dist/workflows/workflows.controller.js.map +1 -1
  302. package/package.json +28 -23
  303. package/templates/form-trigger-completion.handlebars +1 -1
  304. package/dist/auth/index.d.ts +0 -1
  305. package/dist/auth/index.js +0 -18
  306. package/dist/auth/index.js.map +0 -1
  307. package/dist/auth/methods/email.d.ts +0 -2
  308. package/dist/auth/methods/email.js +0 -26
  309. package/dist/auth/methods/email.js.map +0 -1
  310. package/dist/modules/external-secrets.ee/secrets-providers-autocomplete.controller.ee.d.ts +0 -11
  311. package/dist/modules/external-secrets.ee/secrets-providers-autocomplete.controller.ee.js +0 -64
  312. package/dist/modules/external-secrets.ee/secrets-providers-autocomplete.controller.ee.js.map +0 -1
@@ -18,6 +18,7 @@ const n8n_workflow_1 = require("n8n-workflow");
18
18
  const forbidden_error_1 = require("../../errors/response-errors/forbidden.error");
19
19
  const event_service_1 = require("../../events/event.service");
20
20
  const source_control_git_service_ee_1 = require("./source-control-git.service.ee");
21
+ const constants_1 = require("./constants");
21
22
  const source_control_helper_ee_1 = require("./source-control-helper.ee");
22
23
  const source_control_import_service_ee_1 = require("./source-control-import.service.ee");
23
24
  const source_control_preferences_service_ee_1 = require("./source-control-preferences.service.ee");
@@ -36,57 +37,62 @@ let SourceControlStatusService = class SourceControlStatusService {
36
37
  get gitFolder() {
37
38
  return this.sourceControlPreferencesService.gitFolder;
38
39
  }
40
+ get dataTableExportFolder() {
41
+ return `${this.gitFolder}/${constants_1.SOURCE_CONTROL_DATATABLES_EXPORT_FOLDER}`;
42
+ }
43
+ convertToStatusResourceOwner(owner) {
44
+ if (!owner) {
45
+ return;
46
+ }
47
+ if (owner.type === 'personal') {
48
+ return;
49
+ }
50
+ if ('teamId' in owner && 'teamName' in owner) {
51
+ return {
52
+ type: 'team',
53
+ projectId: owner.teamId,
54
+ projectName: owner.teamName,
55
+ };
56
+ }
57
+ if ('projectId' in owner) {
58
+ return owner;
59
+ }
60
+ return;
61
+ }
39
62
  async getStatus(user, options) {
40
63
  const context = new source_control_context_1.SourceControlContext(user);
64
+ const collectVerbose = options?.verbose ?? false;
41
65
  if (options.direction === 'pull' && !(0, permissions_1.hasGlobalScope)(user, 'sourceControl:pull')) {
42
66
  throw new forbidden_error_1.ForbiddenError('You do not have permission to pull from source control');
43
67
  }
44
68
  const sourceControlledFiles = [];
45
69
  await this.resetWorkfolder();
46
- const { wfRemoteVersionIds, wfLocalVersionIds, wfMissingInLocal, wfMissingInRemote, wfModifiedInEither, } = await this.getStatusWorkflows(options, context, sourceControlledFiles);
47
- const { credMissingInLocal, credMissingInRemote, credModifiedInEither } = await this.getStatusCredentials(options, context, sourceControlledFiles);
48
- const { varMissingInLocal, varMissingInRemote, varModifiedInEither } = await this.getStatusVariables(options, sourceControlledFiles);
49
- const { tagsMissingInLocal, tagsMissingInRemote, tagsModifiedInEither, mappingsMissingInLocal, mappingsMissingInRemote, } = await this.getStatusTagsMappings(options, context, sourceControlledFiles);
50
- const { foldersMissingInLocal, foldersMissingInRemote, foldersModifiedInEither } = await this.getStatusFoldersMapping(options, context, sourceControlledFiles);
51
- const { projectsRemote, projectsLocal, projectsMissingInLocal, projectsMissingInRemote, projectsModifiedInEither, } = await this.getStatusProjects(options, context, sourceControlledFiles);
70
+ const workflowsStatus = await this.getStatusWorkflows(options, context, sourceControlledFiles, collectVerbose);
71
+ const credentialsStatus = await this.getStatusCredentials(options, context, sourceControlledFiles, collectVerbose);
72
+ const variablesStatus = await this.getStatusVariables(options, sourceControlledFiles, collectVerbose);
73
+ const dataTablesStatus = await this.getStatusDataTables(options, sourceControlledFiles, collectVerbose);
74
+ const tagsMappingsStatus = await this.getStatusTagsMappings(options, context, sourceControlledFiles, collectVerbose);
75
+ const foldersMappingStatus = await this.getStatusFoldersMapping(options, context, sourceControlledFiles, collectVerbose);
76
+ const projectsStatus = await this.getStatusProjects(options, context, sourceControlledFiles, collectVerbose);
52
77
  if (options.direction === 'push') {
53
78
  this.eventService.emit('source-control-user-started-push-ui', (0, source_control_helper_ee_1.getTrackingInformationFromPrePushResult)(user.id, sourceControlledFiles));
54
79
  }
55
80
  else if (options.direction === 'pull') {
56
81
  this.eventService.emit('source-control-user-started-pull-ui', (0, source_control_helper_ee_1.getTrackingInformationFromPullResult)(user.id, sourceControlledFiles));
57
82
  }
58
- if (options?.verbose) {
83
+ if (collectVerbose) {
59
84
  return {
60
- wfRemoteVersionIds,
61
- wfLocalVersionIds,
62
- wfMissingInLocal,
63
- wfMissingInRemote,
64
- wfModifiedInEither,
65
- credMissingInLocal,
66
- credMissingInRemote,
67
- credModifiedInEither,
68
- varMissingInLocal,
69
- varMissingInRemote,
70
- varModifiedInEither,
71
- tagsMissingInLocal,
72
- tagsMissingInRemote,
73
- tagsModifiedInEither,
74
- mappingsMissingInLocal,
75
- mappingsMissingInRemote,
76
- foldersMissingInLocal,
77
- foldersMissingInRemote,
78
- foldersModifiedInEither,
79
- projectsRemote,
80
- projectsLocal,
81
- projectsMissingInLocal,
82
- projectsMissingInRemote,
83
- projectsModifiedInEither,
85
+ ...workflowsStatus,
86
+ ...credentialsStatus,
87
+ ...variablesStatus,
88
+ ...dataTablesStatus,
89
+ ...tagsMappingsStatus,
90
+ ...foldersMappingStatus,
91
+ ...projectsStatus,
84
92
  sourceControlledFiles,
85
93
  };
86
94
  }
87
- else {
88
- return sourceControlledFiles;
89
- }
95
+ return sourceControlledFiles;
90
96
  }
91
97
  async resetWorkfolder() {
92
98
  if (!this.gitService.git) {
@@ -101,12 +107,13 @@ let SourceControlStatusService = class SourceControlStatusService {
101
107
  throw new n8n_workflow_1.UserError(`Unable to fetch updates from git - your folder might be out of sync. Try reconnecting from the Source Control settings page. Git error message: ${error instanceof Error ? error.message : String(error)}`);
102
108
  }
103
109
  }
104
- async getStatusWorkflows(options, context, sourceControlledFiles) {
110
+ async getStatusWorkflows(options, context, sourceControlledFiles, collectVerbose) {
105
111
  const wfRemoteVersionIds = await this.sourceControlImportService.getRemoteVersionIdsFromFiles(context);
106
112
  const wfLocalVersionIds = await this.sourceControlImportService.getLocalVersionIdsFromDb(context);
107
- const candidateIds = [
108
- ...new Set([...wfLocalVersionIds.map((w) => w.id), ...wfRemoteVersionIds.map((w) => w.id)]),
109
- ];
113
+ const wfRemoteById = new Map(wfRemoteVersionIds.map((w) => [w.id, w]));
114
+ const wfRemoteIds = new Set(wfRemoteVersionIds.map((w) => w.id));
115
+ const wfLocalIds = new Set(wfLocalVersionIds.map((w) => w.id));
116
+ const candidateIds = [...new Set([...wfLocalIds, ...wfRemoteIds])];
110
117
  const localWorkflowsWithStatus = await this.workflowRepository.findByIds(candidateIds, {
111
118
  fields: ['id', 'activeVersionId'],
112
119
  });
@@ -115,84 +122,91 @@ let SourceControlStatusService = class SourceControlStatusService {
115
122
  let outOfScopeWF = [];
116
123
  if (!context.hasAccessToAllProjects()) {
117
124
  outOfScopeWF = await this.sourceControlImportService.getAllLocalVersionIdsFromDb();
118
- outOfScopeWF = outOfScopeWF.filter((wf) => !wfLocalVersionIds.some((local) => local.id === wf.id));
125
+ outOfScopeWF = outOfScopeWF.filter((wf) => !wfLocalIds.has(wf.id));
119
126
  }
120
- const wfMissingInLocal = wfRemoteVersionIds
121
- .filter((remote) => wfLocalVersionIds.findIndex((local) => local.id === remote.id) === -1)
122
- .filter((remote) => !outOfScopeWF.some((outOfScope) => outOfScope.id === remote.id));
123
- const wfMissingInRemote = wfLocalVersionIds.filter((local) => wfRemoteVersionIds.findIndex((remote) => remote.id === local.id) === -1);
127
+ const outOfScopeIds = new Set(outOfScopeWF.map((wf) => wf.id));
128
+ const wfMissingInLocal = [];
129
+ const wfMissingInRemote = [];
124
130
  const wfModifiedInEither = [];
125
- wfLocalVersionIds.forEach((localWorkflow) => {
126
- const remoteWorkflowWithSameId = wfRemoteVersionIds.find((removeWorkflow) => removeWorkflow.id === localWorkflow.id);
127
- if (!remoteWorkflowWithSameId) {
128
- return;
131
+ for (const remoteWorkflow of wfRemoteVersionIds) {
132
+ if (!wfLocalIds.has(remoteWorkflow.id) && !outOfScopeIds.has(remoteWorkflow.id)) {
133
+ if (collectVerbose) {
134
+ wfMissingInLocal.push(remoteWorkflow);
135
+ }
136
+ sourceControlledFiles.push({
137
+ id: remoteWorkflow.id,
138
+ name: remoteWorkflow.name ?? 'Workflow',
139
+ type: 'workflow',
140
+ status: options.direction === 'push' ? 'deleted' : 'created',
141
+ location: options.direction === 'push' ? 'local' : 'remote',
142
+ conflict: false,
143
+ file: remoteWorkflow.filename,
144
+ updatedAt: remoteWorkflow.updatedAt ?? new Date().toISOString(),
145
+ isLocalPublished: false,
146
+ isRemoteArchived: archivedWorkflowIds.get(remoteWorkflow.id) ?? false,
147
+ owner: remoteWorkflow.owner,
148
+ });
129
149
  }
130
- if ((0, source_control_helper_ee_1.isWorkflowModified)(localWorkflow, remoteWorkflowWithSameId)) {
131
- let name = (options?.preferLocalVersion ? localWorkflow?.name : remoteWorkflowWithSameId?.name) ??
132
- 'Workflow';
133
- if (localWorkflow.name &&
134
- remoteWorkflowWithSameId?.name &&
135
- localWorkflow.name !== remoteWorkflowWithSameId.name) {
136
- name = options?.preferLocalVersion
137
- ? `${localWorkflow.name} (Remote: ${remoteWorkflowWithSameId.name})`
138
- : (name = `${remoteWorkflowWithSameId.name} (Local: ${localWorkflow.name})`);
150
+ }
151
+ for (const localWorkflow of wfLocalVersionIds) {
152
+ const remoteWorkflowWithSameId = wfRemoteById.get(localWorkflow.id);
153
+ if (!remoteWorkflowWithSameId) {
154
+ if (collectVerbose) {
155
+ wfMissingInRemote.push(localWorkflow);
139
156
  }
140
- wfModifiedInEither.push({
141
- ...localWorkflow,
142
- name,
143
- versionId: options.preferLocalVersion
144
- ? localWorkflow.versionId
145
- : remoteWorkflowWithSameId.versionId,
146
- localId: localWorkflow.versionId,
147
- remoteId: remoteWorkflowWithSameId.versionId,
157
+ sourceControlledFiles.push({
158
+ id: localWorkflow.id,
159
+ name: localWorkflow.name ?? 'Workflow',
160
+ type: 'workflow',
161
+ status: options.direction === 'push' ? 'created' : 'deleted',
162
+ location: options.direction === 'push' ? 'local' : 'remote',
163
+ conflict: options.direction === 'push' ? false : true,
164
+ file: localWorkflow.filename,
165
+ updatedAt: localWorkflow.updatedAt ?? new Date().toISOString(),
166
+ isLocalPublished: publishedWorkflowIds.has(localWorkflow.id),
167
+ isRemoteArchived: false,
168
+ owner: localWorkflow.owner,
148
169
  });
170
+ continue;
171
+ }
172
+ if (!(0, source_control_helper_ee_1.isWorkflowModified)(localWorkflow, remoteWorkflowWithSameId)) {
173
+ continue;
174
+ }
175
+ let name = (options?.preferLocalVersion ? localWorkflow?.name : remoteWorkflowWithSameId?.name) ??
176
+ 'Workflow';
177
+ if (localWorkflow.name &&
178
+ remoteWorkflowWithSameId?.name &&
179
+ localWorkflow.name !== remoteWorkflowWithSameId.name) {
180
+ name = options?.preferLocalVersion
181
+ ? `${localWorkflow.name} (Remote: ${remoteWorkflowWithSameId.name})`
182
+ : (name = `${remoteWorkflowWithSameId.name} (Local: ${localWorkflow.name})`);
183
+ }
184
+ const wfModified = {
185
+ ...localWorkflow,
186
+ name,
187
+ versionId: options.preferLocalVersion
188
+ ? localWorkflow.versionId
189
+ : remoteWorkflowWithSameId.versionId,
190
+ localId: localWorkflow.versionId,
191
+ remoteId: remoteWorkflowWithSameId.versionId,
192
+ };
193
+ if (collectVerbose) {
194
+ wfModifiedInEither.push(wfModified);
149
195
  }
150
- });
151
- wfMissingInLocal.forEach((item) => {
152
- sourceControlledFiles.push({
153
- id: item.id,
154
- name: item.name ?? 'Workflow',
155
- type: 'workflow',
156
- status: options.direction === 'push' ? 'deleted' : 'created',
157
- location: options.direction === 'push' ? 'local' : 'remote',
158
- conflict: false,
159
- file: item.filename,
160
- updatedAt: item.updatedAt ?? new Date().toISOString(),
161
- isLocalPublished: false,
162
- isRemoteArchived: archivedWorkflowIds.get(item.id) ?? false,
163
- owner: item.owner,
164
- });
165
- });
166
- wfMissingInRemote.forEach((item) => {
167
- sourceControlledFiles.push({
168
- id: item.id,
169
- name: item.name ?? 'Workflow',
170
- type: 'workflow',
171
- status: options.direction === 'push' ? 'created' : 'deleted',
172
- location: options.direction === 'push' ? 'local' : 'remote',
173
- conflict: options.direction === 'push' ? false : true,
174
- file: item.filename,
175
- updatedAt: item.updatedAt ?? new Date().toISOString(),
176
- isLocalPublished: publishedWorkflowIds.has(item.id),
177
- isRemoteArchived: false,
178
- owner: item.owner,
179
- });
180
- });
181
- wfModifiedInEither.forEach((item) => {
182
196
  sourceControlledFiles.push({
183
- id: item.id,
184
- name: item.name ?? 'Workflow',
197
+ id: wfModified.id,
198
+ name: wfModified.name ?? 'Workflow',
185
199
  type: 'workflow',
186
200
  status: 'modified',
187
201
  location: options.direction === 'push' ? 'local' : 'remote',
188
202
  conflict: true,
189
- file: item.filename,
190
- updatedAt: item.updatedAt ?? new Date().toISOString(),
191
- isLocalPublished: publishedWorkflowIds.has(item.id),
192
- isRemoteArchived: archivedWorkflowIds.get(item.id) ?? false,
193
- owner: item.owner,
203
+ file: wfModified.filename,
204
+ updatedAt: wfModified.updatedAt ?? new Date().toISOString(),
205
+ isLocalPublished: publishedWorkflowIds.has(wfModified.id),
206
+ isRemoteArchived: archivedWorkflowIds.get(wfModified.id) ?? false,
207
+ owner: wfModified.owner,
194
208
  });
195
- });
209
+ }
196
210
  return {
197
211
  wfRemoteVersionIds,
198
212
  wfLocalVersionIds,
@@ -201,113 +215,135 @@ let SourceControlStatusService = class SourceControlStatusService {
201
215
  wfModifiedInEither,
202
216
  };
203
217
  }
204
- async getStatusCredentials(options, context, sourceControlledFiles) {
218
+ async getStatusCredentials(options, context, sourceControlledFiles, collectVerbose) {
205
219
  const credRemoteIds = await this.sourceControlImportService.getRemoteCredentialsFromFiles(context);
206
220
  const credLocalIds = await this.sourceControlImportService.getLocalCredentialsFromDb(context);
207
- const credMissingInLocal = credRemoteIds.filter((remote) => credLocalIds.findIndex((local) => local.id === remote.id) === -1);
208
- const credMissingInRemote = credLocalIds.filter((local) => credRemoteIds.findIndex((remote) => remote.id === local.id) === -1);
221
+ const credRemoteById = new Map(credRemoteIds.map((cred) => [cred.id, cred]));
222
+ const credLocalIdsSet = new Set(credLocalIds.map((cred) => cred.id));
223
+ const credMissingInLocal = [];
224
+ const credMissingInRemote = [];
209
225
  const credModifiedInEither = [];
210
- credLocalIds.forEach((local) => {
211
- const mismatchingCreds = credRemoteIds.find((remote) => {
212
- return (remote.id === local.id &&
213
- (remote.name !== local.name ||
214
- remote.type !== local.type ||
215
- (0, source_control_helper_ee_1.hasOwnerChanged)(remote.ownedBy, local.ownedBy) ||
216
- (remote.isGlobal ?? false) !== (local.isGlobal ?? false)));
217
- });
218
- if (mismatchingCreds) {
219
- credModifiedInEither.push({
220
- ...local,
221
- name: options?.preferLocalVersion ? local.name : mismatchingCreds.name,
226
+ for (const remoteCredential of credRemoteIds) {
227
+ if (!credLocalIdsSet.has(remoteCredential.id)) {
228
+ if (collectVerbose) {
229
+ credMissingInLocal.push(remoteCredential);
230
+ }
231
+ sourceControlledFiles.push({
232
+ id: remoteCredential.id,
233
+ name: remoteCredential.name ?? 'Credential',
234
+ type: 'credential',
235
+ status: options.direction === 'push' ? 'deleted' : 'created',
236
+ location: options.direction === 'push' ? 'local' : 'remote',
237
+ conflict: false,
238
+ file: remoteCredential.filename,
239
+ updatedAt: new Date().toISOString(),
240
+ owner: remoteCredential.ownedBy,
222
241
  });
223
242
  }
224
- });
225
- credMissingInLocal.forEach((item) => {
226
- sourceControlledFiles.push({
227
- id: item.id,
228
- name: item.name ?? 'Credential',
229
- type: 'credential',
230
- status: options.direction === 'push' ? 'deleted' : 'created',
231
- location: options.direction === 'push' ? 'local' : 'remote',
232
- conflict: false,
233
- file: item.filename,
234
- updatedAt: new Date().toISOString(),
235
- owner: item.ownedBy,
236
- });
237
- });
238
- credMissingInRemote.forEach((item) => {
239
- sourceControlledFiles.push({
240
- id: item.id,
241
- name: item.name ?? 'Credential',
242
- type: 'credential',
243
- status: options.direction === 'push' ? 'created' : 'deleted',
244
- location: options.direction === 'push' ? 'local' : 'remote',
245
- conflict: options.direction === 'push' ? false : true,
246
- file: item.filename,
247
- updatedAt: new Date().toISOString(),
248
- owner: item.ownedBy,
249
- });
250
- });
251
- credModifiedInEither.forEach((item) => {
252
- sourceControlledFiles.push({
253
- id: item.id,
254
- name: item.name ?? 'Credential',
255
- type: 'credential',
256
- status: 'modified',
257
- location: options.direction === 'push' ? 'local' : 'remote',
258
- conflict: true,
259
- file: item.filename,
260
- updatedAt: new Date().toISOString(),
261
- owner: item.ownedBy,
262
- });
263
- });
243
+ }
244
+ for (const localCredential of credLocalIds) {
245
+ const credRemote = credRemoteById.get(localCredential.id);
246
+ if (credRemote) {
247
+ if ((0, source_control_helper_ee_1.areSameCredentials)(localCredential, credRemote)) {
248
+ continue;
249
+ }
250
+ const modifiedCredential = {
251
+ ...localCredential,
252
+ name: options?.preferLocalVersion ? localCredential.name : credRemote.name,
253
+ };
254
+ if (collectVerbose) {
255
+ credModifiedInEither.push(modifiedCredential);
256
+ }
257
+ sourceControlledFiles.push({
258
+ id: modifiedCredential.id,
259
+ name: modifiedCredential.name ?? 'Credential',
260
+ type: 'credential',
261
+ status: 'modified',
262
+ location: options.direction === 'push' ? 'local' : 'remote',
263
+ conflict: true,
264
+ file: modifiedCredential.filename,
265
+ updatedAt: new Date().toISOString(),
266
+ owner: modifiedCredential.ownedBy,
267
+ });
268
+ }
269
+ else {
270
+ if (collectVerbose) {
271
+ credMissingInRemote.push(localCredential);
272
+ }
273
+ sourceControlledFiles.push({
274
+ id: localCredential.id,
275
+ name: localCredential.name ?? 'Credential',
276
+ type: 'credential',
277
+ status: options.direction === 'push' ? 'created' : 'deleted',
278
+ location: options.direction === 'push' ? 'local' : 'remote',
279
+ conflict: options.direction === 'push' ? false : true,
280
+ file: localCredential.filename,
281
+ updatedAt: new Date().toISOString(),
282
+ owner: localCredential.ownedBy,
283
+ });
284
+ }
285
+ }
264
286
  return {
265
287
  credMissingInLocal,
266
288
  credMissingInRemote,
267
289
  credModifiedInEither,
268
290
  };
269
291
  }
270
- async getStatusVariables(options, sourceControlledFiles) {
292
+ async getStatusVariables(options, sourceControlledFiles, collectVerbose) {
271
293
  const varRemoteIds = await this.sourceControlImportService.getRemoteVariablesFromFile();
272
294
  const varLocalIds = await this.sourceControlImportService.getLocalGlobalVariablesFromDb();
273
- const varMissingInLocal = varRemoteIds.filter((remote) => varLocalIds.findIndex((local) => local.id === remote.id) === -1);
274
- const varMissingInRemote = varLocalIds.filter((local) => varRemoteIds.findIndex((remote) => remote.id === local.id) === -1);
295
+ const varRemoteIdsSet = new Set(varRemoteIds.map((remote) => remote.id));
296
+ const varLocalIdsSet = new Set(varLocalIds.map((local) => local.id));
297
+ const varMissingInLocal = [];
298
+ const varMissingInRemote = [];
275
299
  const varModifiedInEither = [];
276
- varLocalIds.forEach((local) => {
277
- const mismatchingIds = varRemoteIds.find((remote) => (remote.id === local.id && remote.key !== local.key) ||
278
- (remote.id !== local.id && remote.key === local.key));
279
- if (mismatchingIds) {
280
- varModifiedInEither.push(options.preferLocalVersion ? local : mismatchingIds);
300
+ for (const remoteVariable of varRemoteIds) {
301
+ if (!varLocalIdsSet.has(remoteVariable.id)) {
302
+ if (collectVerbose) {
303
+ varMissingInLocal.push(remoteVariable);
304
+ }
305
+ sourceControlledFiles.push({
306
+ id: remoteVariable.id,
307
+ name: remoteVariable.key,
308
+ type: 'variables',
309
+ status: options.direction === 'push' ? 'deleted' : 'created',
310
+ location: options.direction === 'push' ? 'local' : 'remote',
311
+ conflict: false,
312
+ file: (0, source_control_helper_ee_1.getVariablesPath)(this.gitFolder),
313
+ updatedAt: new Date().toISOString(),
314
+ });
315
+ }
316
+ }
317
+ for (const localVariable of varLocalIds) {
318
+ if (!varRemoteIdsSet.has(localVariable.id)) {
319
+ if (collectVerbose) {
320
+ varMissingInRemote.push(localVariable);
321
+ }
322
+ sourceControlledFiles.push({
323
+ id: localVariable.id,
324
+ name: localVariable.key,
325
+ type: 'variables',
326
+ status: options.direction === 'push' ? 'created' : 'deleted',
327
+ location: options.direction === 'push' ? 'local' : 'remote',
328
+ conflict: options.direction === 'push' ? false : true,
329
+ file: (0, source_control_helper_ee_1.getVariablesPath)(this.gitFolder),
330
+ updatedAt: new Date().toISOString(),
331
+ });
332
+ }
333
+ }
334
+ for (const localVariable of varLocalIds) {
335
+ const mismatchingIds = varRemoteIds.find((remote) => (remote.id === localVariable.id && remote.key !== localVariable.key) ||
336
+ (remote.id !== localVariable.id && remote.key === localVariable.key));
337
+ if (!mismatchingIds) {
338
+ continue;
339
+ }
340
+ const modified = options.preferLocalVersion ? localVariable : mismatchingIds;
341
+ if (collectVerbose) {
342
+ varModifiedInEither.push(modified);
281
343
  }
282
- });
283
- varMissingInLocal.forEach((item) => {
284
- sourceControlledFiles.push({
285
- id: item.id,
286
- name: item.key,
287
- type: 'variables',
288
- status: options.direction === 'push' ? 'deleted' : 'created',
289
- location: options.direction === 'push' ? 'local' : 'remote',
290
- conflict: false,
291
- file: (0, source_control_helper_ee_1.getVariablesPath)(this.gitFolder),
292
- updatedAt: new Date().toISOString(),
293
- });
294
- });
295
- varMissingInRemote.forEach((item) => {
296
- sourceControlledFiles.push({
297
- id: item.id,
298
- name: item.key,
299
- type: 'variables',
300
- status: options.direction === 'push' ? 'created' : 'deleted',
301
- location: options.direction === 'push' ? 'local' : 'remote',
302
- conflict: options.direction === 'push' ? false : true,
303
- file: (0, source_control_helper_ee_1.getVariablesPath)(this.gitFolder),
304
- updatedAt: new Date().toISOString(),
305
- });
306
- });
307
- varModifiedInEither.forEach((item) => {
308
344
  sourceControlledFiles.push({
309
- id: item.id,
310
- name: item.key,
345
+ id: modified.id,
346
+ name: modified.key,
311
347
  type: 'variables',
312
348
  status: 'modified',
313
349
  location: options.direction === 'push' ? 'local' : 'remote',
@@ -315,14 +351,84 @@ let SourceControlStatusService = class SourceControlStatusService {
315
351
  file: (0, source_control_helper_ee_1.getVariablesPath)(this.gitFolder),
316
352
  updatedAt: new Date().toISOString(),
317
353
  });
318
- });
354
+ }
319
355
  return {
320
356
  varMissingInLocal,
321
357
  varMissingInRemote,
322
358
  varModifiedInEither,
323
359
  };
324
360
  }
325
- async getStatusTagsMappings(options, context, sourceControlledFiles) {
361
+ async getStatusDataTables(options, sourceControlledFiles, collectVerbose) {
362
+ const dataTablesRemote = (await this.sourceControlImportService.getRemoteDataTablesFromFiles()) ?? [];
363
+ const dataTablesLocal = (await this.sourceControlImportService.getLocalDataTablesFromDb()) ?? [];
364
+ const dtMissingInLocal = [];
365
+ const dtMissingInRemote = [];
366
+ const dtModifiedInEither = [];
367
+ for (const remote of dataTablesRemote) {
368
+ if (dataTablesLocal.findIndex((local) => local.id === remote.id) === -1) {
369
+ if (collectVerbose) {
370
+ dtMissingInLocal.push(remote);
371
+ }
372
+ sourceControlledFiles.push({
373
+ id: remote.id,
374
+ name: remote.name,
375
+ type: 'datatable',
376
+ status: options.direction === 'push' ? 'deleted' : 'created',
377
+ location: options.direction === 'push' ? 'local' : 'remote',
378
+ conflict: false,
379
+ file: (0, source_control_helper_ee_1.getDataTableExportPath)(remote.id, this.dataTableExportFolder),
380
+ updatedAt: new Date().toISOString(),
381
+ owner: this.convertToStatusResourceOwner(remote.ownedBy),
382
+ });
383
+ }
384
+ }
385
+ for (const local of dataTablesLocal) {
386
+ const remote = dataTablesRemote.find((r) => r.id === local.id);
387
+ if (!remote) {
388
+ if (collectVerbose) {
389
+ dtMissingInRemote.push(local);
390
+ }
391
+ sourceControlledFiles.push({
392
+ id: local.id,
393
+ name: local.name,
394
+ type: 'datatable',
395
+ status: options.direction === 'push' ? 'created' : 'deleted',
396
+ location: options.direction === 'push' ? 'local' : 'remote',
397
+ conflict: options.direction !== 'push',
398
+ file: (0, source_control_helper_ee_1.getDataTableExportPath)(local.id, this.dataTableExportFolder),
399
+ updatedAt: new Date().toISOString(),
400
+ owner: local.ownedBy ?? undefined,
401
+ });
402
+ continue;
403
+ }
404
+ const hasMismatch = (remote.id === local.id && remote.name !== local.name) ||
405
+ (remote.id !== local.id && remote.name === local.name);
406
+ const isModified = (0, source_control_helper_ee_1.isDataTableModified)(local, remote);
407
+ if (hasMismatch || isModified) {
408
+ const modified = options.preferLocalVersion ? local : remote;
409
+ if (collectVerbose) {
410
+ dtModifiedInEither.push(modified);
411
+ }
412
+ sourceControlledFiles.push({
413
+ id: modified.id,
414
+ name: modified.name,
415
+ type: 'datatable',
416
+ status: 'modified',
417
+ location: options.direction === 'push' ? 'local' : 'remote',
418
+ conflict: true,
419
+ file: (0, source_control_helper_ee_1.getDataTableExportPath)(modified.id, this.dataTableExportFolder),
420
+ updatedAt: new Date().toISOString(),
421
+ owner: this.convertToStatusResourceOwner(modified.ownedBy),
422
+ });
423
+ }
424
+ }
425
+ return {
426
+ dtMissingInLocal,
427
+ dtMissingInRemote,
428
+ dtModifiedInEither,
429
+ };
430
+ }
431
+ async getStatusTagsMappings(options, context, sourceControlledFiles, collectVerbose) {
326
432
  const lastUpdatedTag = await this.tagRepository.find({
327
433
  order: { updatedAt: 'DESC' },
328
434
  take: 1,
@@ -331,46 +437,65 @@ let SourceControlStatusService = class SourceControlStatusService {
331
437
  const lastUpdatedDate = lastUpdatedTag[0]?.updatedAt ?? new Date();
332
438
  const tagMappingsRemote = await this.sourceControlImportService.getRemoteTagsAndMappingsFromFile(context);
333
439
  const tagMappingsLocal = await this.sourceControlImportService.getLocalTagsAndMappingsFromDb(context);
334
- const tagsMissingInLocal = tagMappingsRemote.tags.filter((remote) => tagMappingsLocal.tags.findIndex((local) => local.id === remote.id) === -1);
335
- const tagsMissingInRemote = tagMappingsLocal.tags.filter((local) => tagMappingsRemote.tags.findIndex((remote) => remote.id === local.id) === -1);
440
+ const tagsMissingInLocal = [];
441
+ const tagsMissingInRemote = [];
336
442
  const tagsModifiedInEither = [];
337
- tagMappingsLocal.tags.forEach((local) => {
338
- const mismatchingIds = tagMappingsRemote.tags.find((remote) => remote.id === local.id && remote.name !== local.name);
443
+ const mappingsMissingInLocal = [];
444
+ const mappingsMissingInRemote = [];
445
+ let tagsMissingInLocalCount = 0;
446
+ let tagsMissingInRemoteCount = 0;
447
+ let tagsModifiedInEitherCount = 0;
448
+ let mappingsMissingInLocalCount = 0;
449
+ let mappingsMissingInRemoteCount = 0;
450
+ for (const remote of tagMappingsRemote.tags) {
451
+ if (tagMappingsLocal.tags.findIndex((local) => local.id === remote.id) === -1) {
452
+ tagsMissingInLocalCount += 1;
453
+ if (collectVerbose) {
454
+ tagsMissingInLocal.push(remote);
455
+ }
456
+ sourceControlledFiles.push({
457
+ id: remote.id,
458
+ name: remote.name,
459
+ type: 'tags',
460
+ status: options.direction === 'push' ? 'deleted' : 'created',
461
+ location: options.direction === 'push' ? 'local' : 'remote',
462
+ conflict: false,
463
+ file: (0, source_control_helper_ee_1.getTagsPath)(this.gitFolder),
464
+ updatedAt: lastUpdatedDate.toISOString(),
465
+ });
466
+ }
467
+ }
468
+ for (const localTag of tagMappingsLocal.tags) {
469
+ if (tagMappingsRemote.tags.findIndex((remote) => remote.id === localTag.id) === -1) {
470
+ tagsMissingInRemoteCount += 1;
471
+ if (collectVerbose) {
472
+ tagsMissingInRemote.push(localTag);
473
+ }
474
+ sourceControlledFiles.push({
475
+ id: localTag.id,
476
+ name: localTag.name,
477
+ type: 'tags',
478
+ status: options.direction === 'push' ? 'created' : 'deleted',
479
+ location: options.direction === 'push' ? 'local' : 'remote',
480
+ conflict: options.direction === 'push' ? false : true,
481
+ file: (0, source_control_helper_ee_1.getTagsPath)(this.gitFolder),
482
+ updatedAt: lastUpdatedDate.toISOString(),
483
+ });
484
+ }
485
+ }
486
+ for (const localTag of tagMappingsLocal.tags) {
487
+ const mismatchingIds = tagMappingsRemote.tags.find((remote) => remote.id === localTag.id && remote.name !== localTag.name);
339
488
  if (!mismatchingIds) {
340
- return;
489
+ continue;
490
+ }
491
+ tagsModifiedInEitherCount += 1;
492
+ const modified = options.preferLocalVersion ? localTag : mismatchingIds;
493
+ if (collectVerbose) {
494
+ tagsModifiedInEither.push(modified);
341
495
  }
342
- tagsModifiedInEither.push(options.preferLocalVersion ? local : mismatchingIds);
343
- });
344
- const mappingsMissingInLocal = tagMappingsRemote.mappings.filter((remote) => tagMappingsLocal.mappings.findIndex((local) => local.tagId === remote.tagId && local.workflowId === remote.workflowId) === -1);
345
- const mappingsMissingInRemote = tagMappingsLocal.mappings.filter((local) => tagMappingsRemote.mappings.findIndex((remote) => remote.tagId === local.tagId && remote.workflowId === local.workflowId) === -1);
346
- tagsMissingInLocal.forEach((item) => {
347
- sourceControlledFiles.push({
348
- id: item.id,
349
- name: item.name,
350
- type: 'tags',
351
- status: options.direction === 'push' ? 'deleted' : 'created',
352
- location: options.direction === 'push' ? 'local' : 'remote',
353
- conflict: false,
354
- file: (0, source_control_helper_ee_1.getTagsPath)(this.gitFolder),
355
- updatedAt: lastUpdatedDate.toISOString(),
356
- });
357
- });
358
- tagsMissingInRemote.forEach((item) => {
359
- sourceControlledFiles.push({
360
- id: item.id,
361
- name: item.name,
362
- type: 'tags',
363
- status: options.direction === 'push' ? 'created' : 'deleted',
364
- location: options.direction === 'push' ? 'local' : 'remote',
365
- conflict: options.direction === 'push' ? false : true,
366
- file: (0, source_control_helper_ee_1.getTagsPath)(this.gitFolder),
367
- updatedAt: lastUpdatedDate.toISOString(),
368
- });
369
- });
370
- tagsModifiedInEither.forEach((item) => {
371
496
  sourceControlledFiles.push({
372
- id: item.id,
373
- name: item.name,
497
+ id: modified.id,
498
+ name: modified.name,
374
499
  type: 'tags',
375
500
  status: 'modified',
376
501
  location: options.direction === 'push' ? 'local' : 'remote',
@@ -378,13 +503,31 @@ let SourceControlStatusService = class SourceControlStatusService {
378
503
  file: (0, source_control_helper_ee_1.getTagsPath)(this.gitFolder),
379
504
  updatedAt: lastUpdatedDate.toISOString(),
380
505
  });
381
- });
382
- const hasMappingChanges = mappingsMissingInLocal.length > 0 || mappingsMissingInRemote.length > 0;
383
- const hasTagChanges = tagsMissingInLocal.length > 0 ||
384
- tagsMissingInRemote.length > 0 ||
385
- tagsModifiedInEither.length > 0;
506
+ }
507
+ for (const remoteTagMapping of tagMappingsRemote.mappings) {
508
+ const isMissing = tagMappingsLocal.mappings.findIndex((local) => local.tagId === remoteTagMapping.tagId &&
509
+ local.workflowId === remoteTagMapping.workflowId);
510
+ if (isMissing === -1) {
511
+ mappingsMissingInLocalCount += 1;
512
+ if (collectVerbose) {
513
+ mappingsMissingInLocal.push(remoteTagMapping);
514
+ }
515
+ }
516
+ }
517
+ for (const localTagMapping of tagMappingsLocal.mappings) {
518
+ const isMissing = tagMappingsRemote.mappings.findIndex((remote) => remote.tagId === localTagMapping.tagId &&
519
+ remote.workflowId === localTagMapping.workflowId);
520
+ if (isMissing === -1) {
521
+ mappingsMissingInRemoteCount += 1;
522
+ if (collectVerbose) {
523
+ mappingsMissingInRemote.push(localTagMapping);
524
+ }
525
+ }
526
+ }
527
+ const hasMappingChanges = mappingsMissingInLocalCount > 0 || mappingsMissingInRemoteCount > 0;
528
+ const hasTagChanges = tagsMissingInLocalCount > 0 || tagsMissingInRemoteCount > 0 || tagsModifiedInEitherCount > 0;
386
529
  if (hasMappingChanges && !hasTagChanges) {
387
- const isConflict = options.direction === 'pull' && mappingsMissingInRemote.length > 0;
530
+ const isConflict = options.direction === 'pull' && mappingsMissingInRemoteCount > 0;
388
531
  sourceControlledFiles.push({
389
532
  id: 'tags',
390
533
  name: 'Workflow Tags',
@@ -404,7 +547,7 @@ let SourceControlStatusService = class SourceControlStatusService {
404
547
  mappingsMissingInRemote,
405
548
  };
406
549
  }
407
- async getStatusFoldersMapping(options, context, sourceControlledFiles) {
550
+ async getStatusFoldersMapping(options, context, sourceControlledFiles, collectVerbose) {
408
551
  const lastUpdatedFolder = await this.folderRepository.find({
409
552
  order: { updatedAt: 'DESC' },
410
553
  take: 1,
@@ -413,14 +556,49 @@ let SourceControlStatusService = class SourceControlStatusService {
413
556
  const lastUpdatedDate = lastUpdatedFolder[0]?.updatedAt ?? new Date();
414
557
  const foldersMappingsRemote = await this.sourceControlImportService.getRemoteFoldersAndMappingsFromFile(context);
415
558
  const foldersMappingsLocal = await this.sourceControlImportService.getLocalFoldersAndMappingsFromDb(context);
416
- const foldersMissingInLocal = foldersMappingsRemote.folders.filter((remote) => foldersMappingsLocal.folders.findIndex((local) => local.id === remote.id) === -1);
417
- const foldersMissingInRemote = foldersMappingsLocal.folders.filter((local) => foldersMappingsRemote.folders.findIndex((remote) => remote.id === local.id) === -1);
559
+ const foldersMissingInLocal = [];
560
+ const foldersMissingInRemote = [];
418
561
  const allTeamProjects = await this.sourceControlImportService.getLocalTeamProjectsFromDb();
419
562
  const foldersModifiedInEither = [];
420
- foldersMappingsLocal.folders.forEach((local) => {
421
- const localHomeProject = allTeamProjects.find((project) => project.id === local.homeProjectId);
563
+ for (const remoteFolder of foldersMappingsRemote.folders) {
564
+ if (foldersMappingsLocal.folders.findIndex((local) => local.id === remoteFolder.id) === -1) {
565
+ if (collectVerbose) {
566
+ foldersMissingInLocal.push(remoteFolder);
567
+ }
568
+ sourceControlledFiles.push({
569
+ id: remoteFolder.id,
570
+ name: remoteFolder.name,
571
+ type: 'folders',
572
+ status: options.direction === 'push' ? 'deleted' : 'created',
573
+ location: options.direction === 'push' ? 'local' : 'remote',
574
+ conflict: false,
575
+ file: (0, source_control_helper_ee_1.getFoldersPath)(this.gitFolder),
576
+ updatedAt: lastUpdatedDate.toISOString(),
577
+ });
578
+ }
579
+ }
580
+ for (const localFolder of foldersMappingsLocal.folders) {
581
+ if (foldersMappingsRemote.folders.findIndex((remote) => remote.id === localFolder.id) === -1) {
582
+ if (collectVerbose) {
583
+ foldersMissingInRemote.push(localFolder);
584
+ }
585
+ sourceControlledFiles.push({
586
+ id: localFolder.id,
587
+ name: localFolder.name,
588
+ type: 'folders',
589
+ status: options.direction === 'push' ? 'created' : 'deleted',
590
+ location: options.direction === 'push' ? 'local' : 'remote',
591
+ conflict: options.direction === 'push' ? false : true,
592
+ file: (0, source_control_helper_ee_1.getFoldersPath)(this.gitFolder),
593
+ updatedAt: lastUpdatedDate.toISOString(),
594
+ });
595
+ }
596
+ }
597
+ const teamProjectsById = new Map(allTeamProjects.map((project) => [project.id, project]));
598
+ for (const localFolder of foldersMappingsLocal.folders) {
599
+ const localHomeProject = teamProjectsById.get(localFolder.homeProjectId);
422
600
  const mismatchingIds = foldersMappingsRemote.folders.find((remote) => {
423
- const remoteHomeProject = allTeamProjects.find((project) => project.id === remote.homeProjectId);
601
+ const remoteHomeProject = teamProjectsById.get(remote.homeProjectId);
424
602
  const localOwner = localHomeProject
425
603
  ? {
426
604
  type: 'team',
@@ -436,44 +614,21 @@ let SourceControlStatusService = class SourceControlStatusService {
436
614
  }
437
615
  : undefined;
438
616
  const ownerChanged = (0, source_control_helper_ee_1.hasOwnerChanged)(localOwner, remoteOwner);
439
- return (remote.id === local.id &&
440
- (remote.name !== local.name ||
441
- remote.parentFolderId !== local.parentFolderId ||
617
+ return (remote.id === localFolder.id &&
618
+ (remote.name !== localFolder.name ||
619
+ remote.parentFolderId !== localFolder.parentFolderId ||
442
620
  ownerChanged));
443
621
  });
444
622
  if (!mismatchingIds) {
445
- return;
623
+ continue;
624
+ }
625
+ const modified = options.preferLocalVersion ? localFolder : mismatchingIds;
626
+ if (collectVerbose) {
627
+ foldersModifiedInEither.push(modified);
446
628
  }
447
- foldersModifiedInEither.push(options.preferLocalVersion ? local : mismatchingIds);
448
- });
449
- foldersMissingInLocal.forEach((item) => {
450
- sourceControlledFiles.push({
451
- id: item.id,
452
- name: item.name,
453
- type: 'folders',
454
- status: options.direction === 'push' ? 'deleted' : 'created',
455
- location: options.direction === 'push' ? 'local' : 'remote',
456
- conflict: false,
457
- file: (0, source_control_helper_ee_1.getFoldersPath)(this.gitFolder),
458
- updatedAt: lastUpdatedDate.toISOString(),
459
- });
460
- });
461
- foldersMissingInRemote.forEach((item) => {
462
- sourceControlledFiles.push({
463
- id: item.id,
464
- name: item.name,
465
- type: 'folders',
466
- status: options.direction === 'push' ? 'created' : 'deleted',
467
- location: options.direction === 'push' ? 'local' : 'remote',
468
- conflict: options.direction === 'push' ? false : true,
469
- file: (0, source_control_helper_ee_1.getFoldersPath)(this.gitFolder),
470
- updatedAt: lastUpdatedDate.toISOString(),
471
- });
472
- });
473
- foldersModifiedInEither.forEach((item) => {
474
629
  sourceControlledFiles.push({
475
- id: item.id,
476
- name: item.name,
630
+ id: modified.id,
631
+ name: modified.name,
477
632
  type: 'folders',
478
633
  status: 'modified',
479
634
  location: options.direction === 'push' ? 'local' : 'remote',
@@ -481,14 +636,14 @@ let SourceControlStatusService = class SourceControlStatusService {
481
636
  file: (0, source_control_helper_ee_1.getFoldersPath)(this.gitFolder),
482
637
  updatedAt: lastUpdatedDate.toISOString(),
483
638
  });
484
- });
639
+ }
485
640
  return {
486
641
  foldersMissingInLocal,
487
642
  foldersMissingInRemote,
488
643
  foldersModifiedInEither,
489
644
  };
490
645
  }
491
- async getStatusProjects(options, context, sourceControlledFiles) {
646
+ async getStatusProjects(options, context, sourceControlledFiles, collectVerbose) {
492
647
  const projectsRemote = await this.sourceControlImportService.getRemoteProjectsFromFiles(context);
493
648
  const projectsLocal = await this.sourceControlImportService.getLocalTeamProjectsFromDb(context);
494
649
  let outOfScopeProjects = [];
@@ -496,17 +651,58 @@ let SourceControlStatusService = class SourceControlStatusService {
496
651
  outOfScopeProjects = await this.sourceControlImportService.getLocalTeamProjectsFromDb();
497
652
  outOfScopeProjects = outOfScopeProjects.filter((project) => !projectsLocal.some((local) => local.id === project.id));
498
653
  }
499
- const projectsMissingInLocal = projectsRemote
500
- .filter((remote) => !projectsLocal.some((local) => local.id === remote.id))
501
- .filter((remote) => !outOfScopeProjects.some((outOfScope) => outOfScope.id === remote.id));
654
+ const projectsMissingInLocal = [];
502
655
  const areRemoteProjectsEmpty = projectsRemote.length === 0;
503
- let projectsMissingInRemote = projectsLocal.filter((local) => !projectsRemote.some((remote) => remote.id === local.id));
504
- if (options.direction === 'pull' && areRemoteProjectsEmpty) {
505
- projectsMissingInRemote = [];
506
- }
656
+ const projectsMissingInRemote = [];
507
657
  const projectsModifiedInEither = [];
658
+ const projectLocalIds = new Set(projectsLocal.map((localProject) => localProject.id));
659
+ const projectRemoteById = new Map(projectsRemote.map((remoteProject) => [remoteProject.id, remoteProject]));
660
+ const outOfScopeProjectIds = new Set(outOfScopeProjects.map((outOfScope) => outOfScope.id));
661
+ const mapExportableProjectWithFileNameToSourceControlledFile = ({ project, status, conflict, }) => {
662
+ return {
663
+ id: project.id,
664
+ name: project.name ?? 'Project',
665
+ type: 'project',
666
+ status,
667
+ location: options.direction === 'push' ? 'local' : 'remote',
668
+ conflict,
669
+ file: project.filename,
670
+ updatedAt: new Date().toISOString(),
671
+ owner: {
672
+ type: project.owner.type,
673
+ projectId: project.owner.teamId,
674
+ projectName: project.owner.teamName,
675
+ },
676
+ };
677
+ };
678
+ for (const remoteProject of projectsRemote) {
679
+ if (!projectLocalIds.has(remoteProject.id) && !outOfScopeProjectIds.has(remoteProject.id)) {
680
+ if (collectVerbose) {
681
+ projectsMissingInLocal.push(remoteProject);
682
+ }
683
+ sourceControlledFiles.push(mapExportableProjectWithFileNameToSourceControlledFile({
684
+ project: remoteProject,
685
+ status: options.direction === 'push' ? 'deleted' : 'created',
686
+ conflict: false,
687
+ }));
688
+ }
689
+ }
690
+ if (!(options.direction === 'pull' && areRemoteProjectsEmpty)) {
691
+ for (const localProject of projectsLocal) {
692
+ if (!projectRemoteById.has(localProject.id)) {
693
+ if (collectVerbose) {
694
+ projectsMissingInRemote.push(localProject);
695
+ }
696
+ sourceControlledFiles.push(mapExportableProjectWithFileNameToSourceControlledFile({
697
+ project: localProject,
698
+ status: options.direction === 'push' ? 'created' : 'deleted',
699
+ conflict: options.direction === 'push' ? false : true,
700
+ }));
701
+ }
702
+ }
703
+ }
508
704
  projectsLocal.forEach((localProject) => {
509
- const remoteProjectWithSameId = projectsRemote.find((remoteProject) => remoteProject.id === localProject.id);
705
+ const remoteProjectWithSameId = projectRemoteById.get(localProject.id);
510
706
  if (!remoteProjectWithSameId) {
511
707
  return;
512
708
  }
@@ -520,7 +716,7 @@ let SourceControlStatusService = class SourceControlStatusService {
520
716
  ? `${localProject.name} (Remote: ${remoteProjectWithSameId.name})`
521
717
  : `${remoteProjectWithSameId.name} (Local: ${localProject.name})`;
522
718
  }
523
- projectsModifiedInEither.push({
719
+ const modified = {
524
720
  ...localProject,
525
721
  name,
526
722
  description: options.preferLocalVersion
@@ -530,47 +726,17 @@ let SourceControlStatusService = class SourceControlStatusService {
530
726
  variableStubs: options.preferLocalVersion
531
727
  ? localProject.variableStubs
532
728
  : remoteProjectWithSameId.variableStubs,
533
- });
729
+ };
730
+ if (collectVerbose) {
731
+ projectsModifiedInEither.push(modified);
732
+ }
733
+ sourceControlledFiles.push(mapExportableProjectWithFileNameToSourceControlledFile({
734
+ project: modified,
735
+ status: 'modified',
736
+ conflict: true,
737
+ }));
534
738
  }
535
739
  });
536
- const mapExportableProjectWithFileNameToSourceControlledFile = ({ project, status, conflict, }) => {
537
- return {
538
- id: project.id,
539
- name: project.name ?? 'Project',
540
- type: 'project',
541
- status,
542
- location: options.direction === 'push' ? 'local' : 'remote',
543
- conflict,
544
- file: project.filename,
545
- updatedAt: new Date().toISOString(),
546
- owner: {
547
- type: project.owner.type,
548
- projectId: project.owner.teamId,
549
- projectName: project.owner.teamName,
550
- },
551
- };
552
- };
553
- projectsMissingInLocal.forEach((item) => {
554
- sourceControlledFiles.push(mapExportableProjectWithFileNameToSourceControlledFile({
555
- project: item,
556
- status: options.direction === 'push' ? 'deleted' : 'created',
557
- conflict: false,
558
- }));
559
- });
560
- projectsMissingInRemote.forEach((item) => {
561
- sourceControlledFiles.push(mapExportableProjectWithFileNameToSourceControlledFile({
562
- project: item,
563
- status: options.direction === 'push' ? 'created' : 'deleted',
564
- conflict: options.direction === 'push' ? false : true,
565
- }));
566
- });
567
- projectsModifiedInEither.forEach((item) => {
568
- sourceControlledFiles.push(mapExportableProjectWithFileNameToSourceControlledFile({
569
- project: item,
570
- status: 'modified',
571
- conflict: true,
572
- }));
573
- });
574
740
  return {
575
741
  projectsRemote,
576
742
  projectsLocal,