reviewflow 3.39.2 → 3.40.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 (171) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/dist/config/projectConfig.d.ts +1 -0
  3. package/dist/config/projectConfig.d.ts.map +1 -1
  4. package/dist/config/projectConfig.js +13 -0
  5. package/dist/config/projectConfig.js.map +1 -1
  6. package/dist/frameworks/config/configLoader.d.ts +1 -0
  7. package/dist/frameworks/config/configLoader.d.ts.map +1 -1
  8. package/dist/frameworks/config/configLoader.js +15 -1
  9. package/dist/frameworks/config/configLoader.js.map +1 -1
  10. package/dist/main/routes.d.ts.map +1 -1
  11. package/dist/main/routes.js +44 -11
  12. package/dist/main/routes.js.map +1 -1
  13. package/dist/modules/platform-integration/entities/webhookEvent/webhookEvent.d.ts +38 -0
  14. package/dist/modules/platform-integration/entities/webhookEvent/webhookEvent.d.ts.map +1 -0
  15. package/dist/modules/platform-integration/entities/webhookEvent/webhookEvent.js +2 -0
  16. package/dist/modules/platform-integration/entities/webhookEvent/webhookEvent.js.map +1 -0
  17. package/dist/modules/platform-integration/interface-adapters/controllers/webhook/diffSizeGuard.helper.d.ts +31 -0
  18. package/dist/modules/platform-integration/interface-adapters/controllers/webhook/diffSizeGuard.helper.d.ts.map +1 -0
  19. package/dist/modules/platform-integration/interface-adapters/controllers/webhook/diffSizeGuard.helper.js +57 -0
  20. package/dist/modules/platform-integration/interface-adapters/controllers/webhook/diffSizeGuard.helper.js.map +1 -0
  21. package/dist/modules/platform-integration/interface-adapters/controllers/webhook/github.controller.d.ts +5 -0
  22. package/dist/modules/platform-integration/interface-adapters/controllers/webhook/github.controller.d.ts.map +1 -1
  23. package/dist/modules/platform-integration/interface-adapters/controllers/webhook/github.controller.js +83 -32
  24. package/dist/modules/platform-integration/interface-adapters/controllers/webhook/github.controller.js.map +1 -1
  25. package/dist/modules/platform-integration/interface-adapters/controllers/webhook/gitlab.controller.d.ts +5 -0
  26. package/dist/modules/platform-integration/interface-adapters/controllers/webhook/gitlab.controller.d.ts.map +1 -1
  27. package/dist/modules/platform-integration/interface-adapters/controllers/webhook/gitlab.controller.js +94 -58
  28. package/dist/modules/platform-integration/interface-adapters/controllers/webhook/gitlab.controller.js.map +1 -1
  29. package/dist/modules/platform-integration/interface-adapters/gateways/changedFilesFetch.github.gateway.d.ts +10 -0
  30. package/dist/modules/platform-integration/interface-adapters/gateways/changedFilesFetch.github.gateway.d.ts.map +1 -0
  31. package/dist/modules/platform-integration/interface-adapters/gateways/changedFilesFetch.github.gateway.js +37 -0
  32. package/dist/modules/platform-integration/interface-adapters/gateways/changedFilesFetch.github.gateway.js.map +1 -0
  33. package/dist/modules/platform-integration/interface-adapters/gateways/changedFilesFetch.gitlab.gateway.d.ts +10 -0
  34. package/dist/modules/platform-integration/interface-adapters/gateways/changedFilesFetch.gitlab.gateway.d.ts.map +1 -0
  35. package/dist/modules/platform-integration/interface-adapters/gateways/changedFilesFetch.gitlab.gateway.js +41 -0
  36. package/dist/modules/platform-integration/interface-adapters/gateways/changedFilesFetch.gitlab.gateway.js.map +1 -0
  37. package/dist/modules/platform-integration/usecases/guardDiffSize.usecase.d.ts +26 -0
  38. package/dist/modules/platform-integration/usecases/guardDiffSize.usecase.d.ts.map +1 -0
  39. package/dist/modules/platform-integration/usecases/guardDiffSize.usecase.js +42 -0
  40. package/dist/modules/platform-integration/usecases/guardDiffSize.usecase.js.map +1 -0
  41. package/dist/modules/platform-integration/usecases/processWebhook.usecase.d.ts +37 -0
  42. package/dist/modules/platform-integration/usecases/processWebhook.usecase.d.ts.map +1 -0
  43. package/dist/modules/platform-integration/usecases/processWebhook.usecase.js +94 -0
  44. package/dist/modules/platform-integration/usecases/processWebhook.usecase.js.map +1 -0
  45. package/dist/modules/shared-kernel/entities/diffSizeGate/changedFilesFetch.gateway.d.ts +5 -0
  46. package/dist/modules/shared-kernel/entities/diffSizeGate/changedFilesFetch.gateway.d.ts.map +1 -0
  47. package/dist/modules/shared-kernel/entities/diffSizeGate/changedFilesFetch.gateway.js +2 -0
  48. package/dist/modules/shared-kernel/entities/diffSizeGate/changedFilesFetch.gateway.js.map +1 -0
  49. package/dist/modules/shared-kernel/entities/diffSizeGate/diffSizeGate.d.ts +17 -0
  50. package/dist/modules/shared-kernel/entities/diffSizeGate/diffSizeGate.d.ts.map +1 -0
  51. package/dist/modules/shared-kernel/entities/diffSizeGate/diffSizeGate.js +20 -0
  52. package/dist/modules/shared-kernel/entities/diffSizeGate/diffSizeGate.js.map +1 -0
  53. package/dist/modules/shared-kernel/entities/diffStats/diffStatsFetch.gateway.d.ts +1 -1
  54. package/dist/modules/shared-kernel/entities/diffStats/diffStatsFetch.gateway.d.ts.map +1 -1
  55. package/dist/modules/statistics-insights/entities/projectIdentifier/projectIdentifier.d.ts +2 -0
  56. package/dist/modules/statistics-insights/entities/projectIdentifier/projectIdentifier.d.ts.map +1 -0
  57. package/dist/modules/statistics-insights/entities/projectIdentifier/projectIdentifier.js +12 -0
  58. package/dist/modules/statistics-insights/entities/projectIdentifier/projectIdentifier.js.map +1 -0
  59. package/dist/modules/statistics-insights/interface-adapters/controllers/http/stats.routes.d.ts +2 -1
  60. package/dist/modules/statistics-insights/interface-adapters/controllers/http/stats.routes.d.ts.map +1 -1
  61. package/dist/modules/statistics-insights/interface-adapters/controllers/http/stats.routes.js +23 -2
  62. package/dist/modules/statistics-insights/interface-adapters/controllers/http/stats.routes.js.map +1 -1
  63. package/dist/modules/statistics-insights/usecases/insights/computeInsightsWithPersistence.usecase.d.ts.map +1 -1
  64. package/dist/modules/statistics-insights/usecases/insights/computeInsightsWithPersistence.usecase.js +46 -8
  65. package/dist/modules/statistics-insights/usecases/insights/computeInsightsWithPersistence.usecase.js.map +1 -1
  66. package/dist/modules/statistics-insights/usecases/stats/backfillDiffStats.usecase.d.ts +1 -0
  67. package/dist/modules/statistics-insights/usecases/stats/backfillDiffStats.usecase.d.ts.map +1 -1
  68. package/dist/modules/statistics-insights/usecases/stats/backfillDiffStats.usecase.js +2 -2
  69. package/dist/modules/statistics-insights/usecases/stats/backfillDiffStats.usecase.js.map +1 -1
  70. package/dist/modules/statistics-insights/usecases/stats/recalculateProjectStats.usecase.d.ts.map +1 -1
  71. package/dist/modules/statistics-insights/usecases/stats/recalculateProjectStats.usecase.js +2 -0
  72. package/dist/modules/statistics-insights/usecases/stats/recalculateProjectStats.usecase.js.map +1 -1
  73. package/dist/modules/statistics-insights/usecases/stats/recalculateWithBackfill.usecase.d.ts +1 -0
  74. package/dist/modules/statistics-insights/usecases/stats/recalculateWithBackfill.usecase.d.ts.map +1 -1
  75. package/dist/modules/statistics-insights/usecases/stats/recalculateWithBackfill.usecase.js +3 -2
  76. package/dist/modules/statistics-insights/usecases/stats/recalculateWithBackfill.usecase.js.map +1 -1
  77. package/dist/modules/tracking/interface-adapters/controllers/http/mrTracking.routes.d.ts +2 -0
  78. package/dist/modules/tracking/interface-adapters/controllers/http/mrTracking.routes.d.ts.map +1 -1
  79. package/dist/modules/tracking/interface-adapters/controllers/http/mrTracking.routes.js +6 -3
  80. package/dist/modules/tracking/interface-adapters/controllers/http/mrTracking.routes.js.map +1 -1
  81. package/dist/modules/tracking/interface-adapters/presenters/mrDiffStats.presenter.d.ts +13 -0
  82. package/dist/modules/tracking/interface-adapters/presenters/mrDiffStats.presenter.d.ts.map +1 -0
  83. package/dist/modules/tracking/interface-adapters/presenters/mrDiffStats.presenter.js +28 -0
  84. package/dist/modules/tracking/interface-adapters/presenters/mrDiffStats.presenter.js.map +1 -0
  85. package/dist/tests/acceptance/180-quality-threshold-block-approval-iter-C.acceptance.test.js +4 -0
  86. package/dist/tests/acceptance/180-quality-threshold-block-approval-iter-C.acceptance.test.js.map +1 -1
  87. package/dist/tests/acceptance/197-trusted-actor-provenance-gate.acceptance.test.js +30 -10
  88. package/dist/tests/acceptance/197-trusted-actor-provenance-gate.acceptance.test.js.map +1 -1
  89. package/dist/tests/acceptance/200-webhook-event-idempotency.acceptance.test.js +30 -10
  90. package/dist/tests/acceptance/200-webhook-event-idempotency.acceptance.test.js.map +1 -1
  91. package/dist/tests/acceptance/208-self-service-backfill-button.acceptance.test.d.ts +2 -0
  92. package/dist/tests/acceptance/208-self-service-backfill-button.acceptance.test.d.ts.map +1 -0
  93. package/dist/tests/acceptance/208-self-service-backfill-button.acceptance.test.js +151 -0
  94. package/dist/tests/acceptance/208-self-service-backfill-button.acceptance.test.js.map +1 -0
  95. package/dist/tests/acceptance/209-mr-size-guard.acceptance.test.d.ts +19 -0
  96. package/dist/tests/acceptance/209-mr-size-guard.acceptance.test.d.ts.map +1 -0
  97. package/dist/tests/acceptance/209-mr-size-guard.acceptance.test.js +181 -0
  98. package/dist/tests/acceptance/209-mr-size-guard.acceptance.test.js.map +1 -0
  99. package/dist/tests/acceptance/46-github-followup-review-on-push.acceptance.test.js +16 -0
  100. package/dist/tests/acceptance/46-github-followup-review-on-push.acceptance.test.js.map +1 -1
  101. package/dist/tests/acceptance/73-process-webhook.acceptance.test.d.ts +2 -0
  102. package/dist/tests/acceptance/73-process-webhook.acceptance.test.d.ts.map +1 -0
  103. package/dist/tests/acceptance/73-process-webhook.acceptance.test.js +161 -0
  104. package/dist/tests/acceptance/73-process-webhook.acceptance.test.js.map +1 -0
  105. package/dist/tests/factories/changedFiles.factory.d.ts +6 -0
  106. package/dist/tests/factories/changedFiles.factory.d.ts.map +1 -0
  107. package/dist/tests/factories/changedFiles.factory.js +14 -0
  108. package/dist/tests/factories/changedFiles.factory.js.map +1 -0
  109. package/dist/tests/stubs/changedFilesFetch.stub.d.ts +12 -0
  110. package/dist/tests/stubs/changedFilesFetch.stub.d.ts.map +1 -0
  111. package/dist/tests/stubs/changedFilesFetch.stub.js +21 -0
  112. package/dist/tests/stubs/changedFilesFetch.stub.js.map +1 -0
  113. package/dist/tests/stubs/diffStatsFetch.stub.d.ts +2 -1
  114. package/dist/tests/stubs/diffStatsFetch.stub.d.ts.map +1 -1
  115. package/dist/tests/stubs/diffStatsFetch.stub.js +3 -1
  116. package/dist/tests/stubs/diffStatsFetch.stub.js.map +1 -1
  117. package/dist/tests/units/config/projectConfig.test.js +49 -0
  118. package/dist/tests/units/config/projectConfig.test.js.map +1 -1
  119. package/dist/tests/units/frameworks/config/configLoader.test.js +20 -0
  120. package/dist/tests/units/frameworks/config/configLoader.test.js.map +1 -1
  121. package/dist/tests/units/interface-adapters/controllers/http/statsRecalculate.routes.test.js +100 -6
  122. package/dist/tests/units/interface-adapters/controllers/http/statsRecalculate.routes.test.js.map +1 -1
  123. package/dist/tests/units/interface-adapters/controllers/webhook/github.controller.test.js +26 -10
  124. package/dist/tests/units/interface-adapters/controllers/webhook/github.controller.test.js.map +1 -1
  125. package/dist/tests/units/interface-adapters/controllers/webhook/gitlab.controller.test.js +42 -11
  126. package/dist/tests/units/interface-adapters/controllers/webhook/gitlab.controller.test.js.map +1 -1
  127. package/dist/tests/units/modules/platform-integration/interface-adapters/controllers/webhook/diffSizeGuard.helper.test.d.ts +2 -0
  128. package/dist/tests/units/modules/platform-integration/interface-adapters/controllers/webhook/diffSizeGuard.helper.test.d.ts.map +1 -0
  129. package/dist/tests/units/modules/platform-integration/interface-adapters/controllers/webhook/diffSizeGuard.helper.test.js +148 -0
  130. package/dist/tests/units/modules/platform-integration/interface-adapters/controllers/webhook/diffSizeGuard.helper.test.js.map +1 -0
  131. package/dist/tests/units/modules/platform-integration/interface-adapters/controllers/webhook/gitlabIdempotency.controller.test.js +30 -10
  132. package/dist/tests/units/modules/platform-integration/interface-adapters/controllers/webhook/gitlabIdempotency.controller.test.js.map +1 -1
  133. package/dist/tests/units/modules/platform-integration/interface-adapters/gateways/changedFilesFetch.github.gateway.test.d.ts +2 -0
  134. package/dist/tests/units/modules/platform-integration/interface-adapters/gateways/changedFilesFetch.github.gateway.test.d.ts.map +1 -0
  135. package/dist/tests/units/modules/platform-integration/interface-adapters/gateways/changedFilesFetch.github.gateway.test.js +52 -0
  136. package/dist/tests/units/modules/platform-integration/interface-adapters/gateways/changedFilesFetch.github.gateway.test.js.map +1 -0
  137. package/dist/tests/units/modules/platform-integration/interface-adapters/gateways/changedFilesFetch.gitlab.gateway.test.d.ts +2 -0
  138. package/dist/tests/units/modules/platform-integration/interface-adapters/gateways/changedFilesFetch.gitlab.gateway.test.d.ts.map +1 -0
  139. package/dist/tests/units/modules/platform-integration/interface-adapters/gateways/changedFilesFetch.gitlab.gateway.test.js +57 -0
  140. package/dist/tests/units/modules/platform-integration/interface-adapters/gateways/changedFilesFetch.gitlab.gateway.test.js.map +1 -0
  141. package/dist/tests/units/modules/platform-integration/usecases/guardDiffSize.usecase.test.d.ts +2 -0
  142. package/dist/tests/units/modules/platform-integration/usecases/guardDiffSize.usecase.test.d.ts.map +1 -0
  143. package/dist/tests/units/modules/platform-integration/usecases/guardDiffSize.usecase.test.js +91 -0
  144. package/dist/tests/units/modules/platform-integration/usecases/guardDiffSize.usecase.test.js.map +1 -0
  145. package/dist/tests/units/modules/platform-integration/usecases/processWebhook.usecase.test.d.ts +2 -0
  146. package/dist/tests/units/modules/platform-integration/usecases/processWebhook.usecase.test.d.ts.map +1 -0
  147. package/dist/tests/units/modules/platform-integration/usecases/processWebhook.usecase.test.js +231 -0
  148. package/dist/tests/units/modules/platform-integration/usecases/processWebhook.usecase.test.js.map +1 -0
  149. package/dist/tests/units/modules/shared-kernel/entities/diffSizeGate/diffSizeGate.test.d.ts +2 -0
  150. package/dist/tests/units/modules/shared-kernel/entities/diffSizeGate/diffSizeGate.test.d.ts.map +1 -0
  151. package/dist/tests/units/modules/shared-kernel/entities/diffSizeGate/diffSizeGate.test.js +67 -0
  152. package/dist/tests/units/modules/shared-kernel/entities/diffSizeGate/diffSizeGate.test.js.map +1 -0
  153. package/dist/tests/units/modules/statistics-insights/entities/projectIdentifier/projectIdentifier.test.d.ts +2 -0
  154. package/dist/tests/units/modules/statistics-insights/entities/projectIdentifier/projectIdentifier.test.d.ts.map +1 -0
  155. package/dist/tests/units/modules/statistics-insights/entities/projectIdentifier/projectIdentifier.test.js +29 -0
  156. package/dist/tests/units/modules/statistics-insights/entities/projectIdentifier/projectIdentifier.test.js.map +1 -0
  157. package/dist/tests/units/modules/tracking/interface-adapters/controllers/http/mrTracking.routes.test.js +66 -0
  158. package/dist/tests/units/modules/tracking/interface-adapters/controllers/http/mrTracking.routes.test.js.map +1 -1
  159. package/dist/tests/units/modules/tracking/interface-adapters/presenters/mrDiffStats.presenter.test.d.ts +2 -0
  160. package/dist/tests/units/modules/tracking/interface-adapters/presenters/mrDiffStats.presenter.test.d.ts.map +1 -0
  161. package/dist/tests/units/modules/tracking/interface-adapters/presenters/mrDiffStats.presenter.test.js +84 -0
  162. package/dist/tests/units/modules/tracking/interface-adapters/presenters/mrDiffStats.presenter.test.js.map +1 -0
  163. package/dist/tests/units/usecases/insights/computeInsightsWithPersistence.usecase.test.js +76 -0
  164. package/dist/tests/units/usecases/insights/computeInsightsWithPersistence.usecase.test.js.map +1 -1
  165. package/dist/tests/units/usecases/stats/backfillDiffStats.usecase.test.js +61 -7
  166. package/dist/tests/units/usecases/stats/backfillDiffStats.usecase.test.js.map +1 -1
  167. package/dist/tests/units/usecases/stats/recalculateProjectStats.usecase.test.js +3 -0
  168. package/dist/tests/units/usecases/stats/recalculateProjectStats.usecase.test.js.map +1 -1
  169. package/dist/tests/units/usecases/stats/recalculateWithBackfill.usecase.test.js +38 -6
  170. package/dist/tests/units/usecases/stats/recalculateWithBackfill.usecase.test.js.map +1 -1
  171. package/package.json +1 -1
@@ -0,0 +1,52 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { GitHubChangedFilesFetchGateway } from '../../../../../../modules/platform-integration/interface-adapters/gateways/changedFilesFetch.github.gateway.js';
3
+ describe('GitHubChangedFilesFetchGateway', () => {
4
+ describe('fetchChangedFiles', () => {
5
+ it('maps filename to path from the GitHub pulls/files API', () => {
6
+ const stubExecutor = () => JSON.stringify([
7
+ { filename: 'src/a.ts', additions: 50, deletions: 10 },
8
+ { filename: 'yarn.lock', additions: 5000, deletions: 0 },
9
+ ]);
10
+ const gateway = new GitHubChangedFilesFetchGateway(stubExecutor);
11
+ const result = gateway.fetchChangedFiles('owner/repo', 42);
12
+ expect(result).toEqual([
13
+ { path: 'src/a.ts', additions: 50, deletions: 10 },
14
+ { path: 'yarn.lock', additions: 5000, deletions: 0 },
15
+ ]);
16
+ });
17
+ it('calls the paginated files endpoint for the pull request', () => {
18
+ let capturedCommand = '';
19
+ const stubExecutor = (command) => {
20
+ capturedCommand = command;
21
+ return JSON.stringify([]);
22
+ };
23
+ const gateway = new GitHubChangedFilesFetchGateway(stubExecutor);
24
+ gateway.fetchChangedFiles('owner/repo', 42);
25
+ expect(capturedCommand).toContain('--paginate');
26
+ expect(capturedCommand).toContain('repos/owner/repo/pulls/42/files');
27
+ });
28
+ it('returns null when the executor throws', () => {
29
+ const gateway = new GitHubChangedFilesFetchGateway(() => {
30
+ throw new Error('Network error');
31
+ });
32
+ expect(gateway.fetchChangedFiles('owner/repo', 42)).toBeNull();
33
+ });
34
+ it('returns null when the response is malformed JSON', () => {
35
+ const gateway = new GitHubChangedFilesFetchGateway(() => 'not valid json');
36
+ expect(gateway.fetchChangedFiles('owner/repo', 42)).toBeNull();
37
+ });
38
+ it('returns null when the response is not an array', () => {
39
+ const gateway = new GitHubChangedFilesFetchGateway(() => JSON.stringify({ message: 'nope' }));
40
+ expect(gateway.fetchChangedFiles('owner/repo', 42)).toBeNull();
41
+ });
42
+ it('returns null when an entry has a non-numeric additions field', () => {
43
+ const gateway = new GitHubChangedFilesFetchGateway(() => JSON.stringify([{ filename: 'src/a.ts', additions: 'lots', deletions: 0 }]));
44
+ expect(gateway.fetchChangedFiles('owner/repo', 42)).toBeNull();
45
+ });
46
+ it('returns an empty list for a pull request with no changed files', () => {
47
+ const gateway = new GitHubChangedFilesFetchGateway(() => JSON.stringify([]));
48
+ expect(gateway.fetchChangedFiles('owner/repo', 42)).toEqual([]);
49
+ });
50
+ });
51
+ });
52
+ //# sourceMappingURL=changedFilesFetch.github.gateway.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"changedFilesFetch.github.gateway.test.js","sourceRoot":"","sources":["../../../../../../../src/tests/units/modules/platform-integration/interface-adapters/gateways/changedFilesFetch.github.gateway.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=changedFilesFetch.gitlab.gateway.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"changedFilesFetch.gitlab.gateway.test.d.ts","sourceRoot":"","sources":["../../../../../../../src/tests/units/modules/platform-integration/interface-adapters/gateways/changedFilesFetch.gitlab.gateway.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,57 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { GitLabChangedFilesFetchGateway } from '../../../../../../modules/platform-integration/interface-adapters/gateways/changedFilesFetch.gitlab.gateway.js';
3
+ function graphqlEnvelope(diffStats) {
4
+ return JSON.stringify({ data: { project: { mergeRequest: { diffStats } } } });
5
+ }
6
+ describe('GitLabChangedFilesFetchGateway', () => {
7
+ describe('fetchChangedFiles', () => {
8
+ it('parses the per-file diffStats array from the GraphQL response', () => {
9
+ const stubExecutor = () => graphqlEnvelope([
10
+ { path: 'src/a.ts', additions: 50, deletions: 10 },
11
+ { path: 'yarn.lock', additions: 5000, deletions: 0 },
12
+ ]);
13
+ const gateway = new GitLabChangedFilesFetchGateway(stubExecutor);
14
+ const result = gateway.fetchChangedFiles('group/project', 42);
15
+ expect(result).toEqual([
16
+ { path: 'src/a.ts', additions: 50, deletions: 10 },
17
+ { path: 'yarn.lock', additions: 5000, deletions: 0 },
18
+ ]);
19
+ });
20
+ it('emits a GraphQL query with the raw project fullPath and merge request iid', () => {
21
+ let capturedCommand = '';
22
+ const stubExecutor = (command) => {
23
+ capturedCommand = command;
24
+ return graphqlEnvelope([]);
25
+ };
26
+ const gateway = new GitLabChangedFilesFetchGateway(stubExecutor);
27
+ gateway.fetchChangedFiles('group/project', 99);
28
+ expect(capturedCommand).toContain('graphql');
29
+ expect(capturedCommand).toContain('fullPath:"group/project"');
30
+ expect(capturedCommand).toContain('iid:"99"');
31
+ });
32
+ it('returns null when the executor throws', () => {
33
+ const stubExecutor = () => {
34
+ throw new Error('GraphQL API error');
35
+ };
36
+ const gateway = new GitLabChangedFilesFetchGateway(stubExecutor);
37
+ expect(gateway.fetchChangedFiles('group/project', 42)).toBeNull();
38
+ });
39
+ it('returns null when the response is malformed JSON', () => {
40
+ const gateway = new GitLabChangedFilesFetchGateway(() => 'not valid json');
41
+ expect(gateway.fetchChangedFiles('group/project', 42)).toBeNull();
42
+ });
43
+ it('returns null when diffStats is missing from the response', () => {
44
+ const gateway = new GitLabChangedFilesFetchGateway(() => JSON.stringify({ data: { project: { mergeRequest: null } } }));
45
+ expect(gateway.fetchChangedFiles('group/project', 42)).toBeNull();
46
+ });
47
+ it('returns null when a diffStats entry has a non-numeric additions field', () => {
48
+ const gateway = new GitLabChangedFilesFetchGateway(() => graphqlEnvelope([{ path: 'src/a.ts', additions: 'lots', deletions: 0 }]));
49
+ expect(gateway.fetchChangedFiles('group/project', 42)).toBeNull();
50
+ });
51
+ it('returns an empty list for a merge request with no changed files', () => {
52
+ const gateway = new GitLabChangedFilesFetchGateway(() => graphqlEnvelope([]));
53
+ expect(gateway.fetchChangedFiles('group/project', 42)).toEqual([]);
54
+ });
55
+ });
56
+ });
57
+ //# sourceMappingURL=changedFilesFetch.gitlab.gateway.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"changedFilesFetch.gitlab.gateway.test.js","sourceRoot":"","sources":["../../../../../../../src/tests/units/modules/platform-integration/interface-adapters/gateways/changedFilesFetch.gitlab.gateway.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=guardDiffSize.usecase.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guardDiffSize.usecase.test.d.ts","sourceRoot":"","sources":["../../../../../../src/tests/units/modules/platform-integration/usecases/guardDiffSize.usecase.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,91 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { GuardDiffSizeUseCase } from '../../../../../modules/platform-integration/usecases/guardDiffSize.usecase.js';
3
+ import { ChangedFilesFactory } from '../../../../../tests/factories/changedFiles.factory.js';
4
+ import { StubChangedFilesFetchGateway } from '../../../../../tests/stubs/changedFilesFetch.stub.js';
5
+ function buildUseCase() {
6
+ const gateway = new StubChangedFilesFetchGateway();
7
+ return { gateway, useCase: new GuardDiffSizeUseCase({ changedFilesFetchGateway: gateway }) };
8
+ }
9
+ describe('GuardDiffSizeUseCase', () => {
10
+ it('blocks an oversized merge request with counted lines and budget in the message', () => {
11
+ const { gateway, useCase } = buildUseCase();
12
+ gateway.setResponse(42, ChangedFilesFactory.list([{ path: 'src/big.ts', additions: 2000, deletions: 500 }]));
13
+ const verdict = useCase.execute({
14
+ projectIdentifier: 'group/project',
15
+ mergeRequestNumber: 42,
16
+ budget: 2000,
17
+ });
18
+ expect(verdict.kind).toBe('blocked');
19
+ if (verdict.kind === 'blocked') {
20
+ expect(verdict.countedLines).toBe(2500);
21
+ expect(verdict.budget).toBe(2000);
22
+ expect(verdict.message).toContain('2500');
23
+ expect(verdict.message).toContain('2000');
24
+ }
25
+ });
26
+ it('allows a merge request under the budget without a message', () => {
27
+ const { gateway, useCase } = buildUseCase();
28
+ gateway.setResponse(42, ChangedFilesFactory.list([{ path: 'src/a.ts', additions: 50, deletions: 10 }]));
29
+ const verdict = useCase.execute({
30
+ projectIdentifier: 'group/project',
31
+ mergeRequestNumber: 42,
32
+ budget: 2000,
33
+ });
34
+ expect(verdict).toEqual({ kind: 'allowed' });
35
+ });
36
+ it('posts a French split message mentioning actionable tips', () => {
37
+ const { gateway, useCase } = buildUseCase();
38
+ gateway.setResponse(42, ChangedFilesFactory.list([{ path: 'src/big.ts', additions: 2100, deletions: 0 }]));
39
+ const verdict = useCase.execute({
40
+ projectIdentifier: 'group/project',
41
+ mergeRequestNumber: 42,
42
+ budget: 2000,
43
+ });
44
+ expect(verdict.kind).toBe('blocked');
45
+ if (verdict.kind === 'blocked') {
46
+ expect(verdict.message).toContain('Revue refusée');
47
+ expect(verdict.message).toContain('découpez');
48
+ }
49
+ });
50
+ it('is fail-open when the gateway throws (processed normally, no message)', () => {
51
+ const { gateway, useCase } = buildUseCase();
52
+ gateway.setFailure(42);
53
+ const verdict = useCase.execute({
54
+ projectIdentifier: 'group/project',
55
+ mergeRequestNumber: 42,
56
+ budget: 2000,
57
+ });
58
+ expect(verdict).toEqual({ kind: 'allowed' });
59
+ });
60
+ it('is fail-open when the gateway returns null (no changed files available)', () => {
61
+ const { gateway, useCase } = buildUseCase();
62
+ gateway.setResponse(42, null);
63
+ const verdict = useCase.execute({
64
+ projectIdentifier: 'group/project',
65
+ mergeRequestNumber: 42,
66
+ budget: 2000,
67
+ });
68
+ expect(verdict).toEqual({ kind: 'allowed' });
69
+ });
70
+ it('blocks against a per-repo override budget below the counted size', () => {
71
+ const { gateway, useCase } = buildUseCase();
72
+ gateway.setResponse(42, ChangedFilesFactory.list([{ path: 'src/a.ts', additions: 800, deletions: 0 }]));
73
+ const verdict = useCase.execute({
74
+ projectIdentifier: 'group/project',
75
+ mergeRequestNumber: 42,
76
+ budget: 500,
77
+ });
78
+ expect(verdict.kind).toBe('blocked');
79
+ });
80
+ it('blocks against the default budget when counted size exceeds 2000', () => {
81
+ const { gateway, useCase } = buildUseCase();
82
+ gateway.setResponse(42, ChangedFilesFactory.list([{ path: 'src/a.ts', additions: 2100, deletions: 0 }]));
83
+ const verdict = useCase.execute({
84
+ projectIdentifier: 'group/project',
85
+ mergeRequestNumber: 42,
86
+ budget: 2000,
87
+ });
88
+ expect(verdict.kind).toBe('blocked');
89
+ });
90
+ });
91
+ //# sourceMappingURL=guardDiffSize.usecase.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guardDiffSize.usecase.test.js","sourceRoot":"","sources":["../../../../../../src/tests/units/modules/platform-integration/usecases/guardDiffSize.usecase.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=processWebhook.usecase.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"processWebhook.usecase.test.d.ts","sourceRoot":"","sources":["../../../../../../src/tests/units/modules/platform-integration/usecases/processWebhook.usecase.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,231 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { processWebhook, } from '../../../../../modules/platform-integration/usecases/processWebhook.usecase.js';
3
+ import { TrackedMrFactory } from '../../../../../tests/factories/trackedMr.factory.js';
4
+ import { createStubLogger } from '../../../../../tests/stubs/logger.stub.js';
5
+ function buildHarness(overrides) {
6
+ const handleCloseCalls = [];
7
+ const transitionStateCalls = [];
8
+ const recordPushCalls = [];
9
+ const checkFollowupNeededCalls = [];
10
+ const removeWorktreeCalls = [];
11
+ const deps = {
12
+ handleClose: async (input) => {
13
+ handleCloseCalls.push({
14
+ platform: input.platform,
15
+ mergeRequestNumber: input.mergeRequestNumber,
16
+ localPath: input.localPath,
17
+ });
18
+ return {
19
+ status: 'cleaned',
20
+ jobCancelled: true,
21
+ trackingArchived: false,
22
+ contextDeleted: true,
23
+ };
24
+ },
25
+ transitionState: {
26
+ execute: (input) => {
27
+ transitionStateCalls.push({
28
+ projectPath: input.projectPath,
29
+ mrId: input.mrId,
30
+ targetState: input.targetState,
31
+ });
32
+ return { ok: true };
33
+ },
34
+ },
35
+ recordPush: {
36
+ execute: (input) => {
37
+ recordPushCalls.push({
38
+ projectPath: input.projectPath,
39
+ mrNumber: input.mrNumber,
40
+ platform: input.platform,
41
+ });
42
+ return TrackedMrFactory.create({ mrNumber: input.mrNumber, autoFollowup: true });
43
+ },
44
+ },
45
+ checkFollowupNeeded: {
46
+ execute: (input) => {
47
+ checkFollowupNeededCalls.push({
48
+ projectPath: input.projectPath,
49
+ mrNumber: input.mrNumber,
50
+ platform: input.platform,
51
+ });
52
+ return true;
53
+ },
54
+ },
55
+ removeWorktree: async ({ identity, sourceCheckoutPath }) => {
56
+ removeWorktreeCalls.push({ platform: identity.platform, sourceCheckoutPath });
57
+ return { status: 'removed' };
58
+ },
59
+ logger: createStubLogger(),
60
+ ...overrides,
61
+ };
62
+ return {
63
+ deps,
64
+ handleCloseCalls,
65
+ transitionStateCalls,
66
+ recordPushCalls,
67
+ checkFollowupNeededCalls,
68
+ removeWorktreeCalls,
69
+ };
70
+ }
71
+ const baseClose = {
72
+ type: 'close',
73
+ platform: 'github',
74
+ projectPath: 'org/repo',
75
+ localPath: '/checkout/repo',
76
+ mergeRequestNumber: 7,
77
+ };
78
+ const baseMerge = {
79
+ type: 'merge',
80
+ platform: 'gitlab',
81
+ projectPath: 'group/project',
82
+ localPath: '/checkout/project',
83
+ mergeRequestNumber: 42,
84
+ };
85
+ function followupFor(mrNumber) {
86
+ return {
87
+ type: 'followup-push',
88
+ platform: 'gitlab',
89
+ projectPath: 'group/project',
90
+ localPath: '/checkout/project',
91
+ mergeRequestNumber: mrNumber,
92
+ mergeRequestUrl: `https://gitlab.com/group/project/-/merge_requests/${mrNumber}`,
93
+ sourceBranch: 'fix-bug',
94
+ targetBranch: 'main',
95
+ };
96
+ }
97
+ describe('processWebhook', () => {
98
+ describe('close', () => {
99
+ it('delegates to handleClose with the platform-neutral identity', async () => {
100
+ const harness = buildHarness();
101
+ const result = await processWebhook(baseClose, harness.deps);
102
+ expect(harness.handleCloseCalls).toEqual([
103
+ { platform: 'github', mergeRequestNumber: 7, localPath: '/checkout/repo' },
104
+ ]);
105
+ expect(result).toEqual({
106
+ type: 'closed',
107
+ mergeRequestNumber: 7,
108
+ jobCancelled: true,
109
+ trackingArchived: false,
110
+ });
111
+ });
112
+ });
113
+ describe('merge', () => {
114
+ it('transitions tracking state to merged using the platform-prefixed id', async () => {
115
+ const harness = buildHarness();
116
+ const result = await processWebhook(baseMerge, harness.deps);
117
+ expect(harness.transitionStateCalls).toEqual([
118
+ {
119
+ projectPath: '/checkout/project',
120
+ mrId: 'gitlab-group/project-42',
121
+ targetState: 'merged',
122
+ },
123
+ ]);
124
+ expect(result).toEqual({ type: 'merged', mergeRequestNumber: 42 });
125
+ });
126
+ it('removes the worktree best-effort with the source checkout path', async () => {
127
+ const harness = buildHarness();
128
+ await processWebhook(baseMerge, harness.deps);
129
+ expect(harness.removeWorktreeCalls).toEqual([
130
+ { platform: 'gitlab', sourceCheckoutPath: '/checkout/project' },
131
+ ]);
132
+ });
133
+ it('returns merged even when worktree removal throws', async () => {
134
+ const harness = buildHarness({
135
+ removeWorktree: async () => {
136
+ throw new Error('exploded');
137
+ },
138
+ });
139
+ const result = await processWebhook(baseMerge, harness.deps);
140
+ expect(result).toEqual({ type: 'merged', mergeRequestNumber: 42 });
141
+ });
142
+ });
143
+ describe('followup-push', () => {
144
+ it('records the push then checks followup eligibility', async () => {
145
+ const harness = buildHarness();
146
+ const result = await processWebhook(followupFor(42), harness.deps);
147
+ expect(harness.recordPushCalls).toEqual([
148
+ { projectPath: '/checkout/project', mrNumber: 42, platform: 'gitlab' },
149
+ ]);
150
+ expect(harness.checkFollowupNeededCalls).toEqual([
151
+ { projectPath: '/checkout/project', mrNumber: 42, platform: 'gitlab' },
152
+ ]);
153
+ expect(result).toEqual({ type: 'followup-eligible', mergeRequestNumber: 42 });
154
+ });
155
+ it('skips when the merge request is not tracked', async () => {
156
+ const harness = buildHarness({ recordPush: { execute: () => null } });
157
+ const result = await processWebhook(followupFor(42), harness.deps);
158
+ expect(harness.checkFollowupNeededCalls).toEqual([]);
159
+ expect(result).toEqual({
160
+ type: 'followup-skipped',
161
+ mergeRequestNumber: 42,
162
+ reason: 'Merge request not tracked',
163
+ });
164
+ });
165
+ it('skips when no followup is needed', async () => {
166
+ const harness = buildHarness({ checkFollowupNeeded: { execute: () => false } });
167
+ const result = await processWebhook(followupFor(42), harness.deps);
168
+ expect(result).toEqual({
169
+ type: 'followup-skipped',
170
+ mergeRequestNumber: 42,
171
+ reason: 'No followup needed',
172
+ });
173
+ });
174
+ it('skips when auto-followup is disabled on the tracked merge request', async () => {
175
+ const harness = buildHarness({
176
+ recordPush: {
177
+ execute: () => TrackedMrFactory.create({ mrNumber: 42, autoFollowup: false }),
178
+ },
179
+ });
180
+ const result = await processWebhook(followupFor(42), harness.deps);
181
+ expect(result).toEqual({
182
+ type: 'followup-skipped',
183
+ mergeRequestNumber: 42,
184
+ reason: 'Auto-followup disabled',
185
+ });
186
+ });
187
+ });
188
+ describe('events the controller still owns', () => {
189
+ it('treats review-requested as handled by the controller', async () => {
190
+ const harness = buildHarness();
191
+ const result = await processWebhook({
192
+ type: 'review-requested',
193
+ platform: 'gitlab',
194
+ projectPath: 'group/project',
195
+ localPath: '/checkout/project',
196
+ mergeRequestNumber: 42,
197
+ mergeRequestUrl: 'https://gitlab.com/group/project/-/merge_requests/42',
198
+ sourceBranch: 'fix-bug',
199
+ targetBranch: 'main',
200
+ title: 'Fix bug',
201
+ description: null,
202
+ assignedBy: { username: 'alice', displayName: null },
203
+ skill: 'review',
204
+ language: null,
205
+ }, harness.deps);
206
+ expect(result).toEqual({
207
+ type: 'ignored',
208
+ reason: 'review-requested-handled-by-controller',
209
+ });
210
+ });
211
+ it('treats approve as handled by the controller', async () => {
212
+ const harness = buildHarness();
213
+ const result = await processWebhook({
214
+ type: 'approve',
215
+ platform: 'gitlab',
216
+ projectPath: 'group/project',
217
+ localPath: '/checkout/project',
218
+ mergeRequestNumber: 42,
219
+ }, harness.deps);
220
+ expect(result).toEqual({ type: 'ignored', reason: 'approve-handled-by-controller' });
221
+ });
222
+ });
223
+ describe('ignored', () => {
224
+ it('passes the reason straight through', async () => {
225
+ const harness = buildHarness();
226
+ const result = await processWebhook({ type: 'ignored', reason: 'Not a MR event' }, harness.deps);
227
+ expect(result).toEqual({ type: 'ignored', reason: 'Not a MR event' });
228
+ });
229
+ });
230
+ });
231
+ //# sourceMappingURL=processWebhook.usecase.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"processWebhook.usecase.test.js","sourceRoot":"","sources":["../../../../../../src/tests/units/modules/platform-integration/usecases/processWebhook.usecase.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=diffSizeGate.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diffSizeGate.test.d.ts","sourceRoot":"","sources":["../../../../../../../src/tests/units/modules/shared-kernel/entities/diffSizeGate/diffSizeGate.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,67 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { evaluateDiffSizeGate } from '../../../../../../modules/shared-kernel/entities/diffSizeGate/diffSizeGate.js';
3
+ describe('evaluateDiffSizeGate', () => {
4
+ it('excludes lockfiles from the counted size', () => {
5
+ const result = evaluateDiffSizeGate({
6
+ files: [
7
+ { path: 'yarn.lock', additions: 5000, deletions: 0 },
8
+ { path: 'src/a.ts', additions: 30, deletions: 0 },
9
+ ],
10
+ budget: 2000,
11
+ });
12
+ expect(result.countedLines).toBe(30);
13
+ expect(result.oversized).toBe(false);
14
+ });
15
+ it('excludes package.json from the counted size', () => {
16
+ const result = evaluateDiffSizeGate({
17
+ files: [
18
+ { path: 'package.json', additions: 3000, deletions: 0 },
19
+ { path: 'src/a.ts', additions: 10, deletions: 0 },
20
+ ],
21
+ budget: 2000,
22
+ });
23
+ expect(result.countedLines).toBe(10);
24
+ expect(result.oversized).toBe(false);
25
+ });
26
+ it('excludes a lockfile referenced by a nested path (matched by basename)', () => {
27
+ const result = evaluateDiffSizeGate({
28
+ files: [
29
+ { path: 'frontend/yarn.lock', additions: 4000, deletions: 0 },
30
+ { path: 'src/a.ts', additions: 20, deletions: 5 },
31
+ ],
32
+ budget: 2000,
33
+ });
34
+ expect(result.countedLines).toBe(25);
35
+ });
36
+ it('sums additions and deletions over counted files', () => {
37
+ const result = evaluateDiffSizeGate({
38
+ files: [
39
+ { path: 'src/a.ts', additions: 50, deletions: 10 },
40
+ { path: 'src/b.ts', additions: 5, deletions: 5 },
41
+ ],
42
+ budget: 2000,
43
+ });
44
+ expect(result.countedLines).toBe(70);
45
+ });
46
+ it('is not oversized when the counted size equals the budget', () => {
47
+ const result = evaluateDiffSizeGate({
48
+ files: [{ path: 'src/a.ts', additions: 2000, deletions: 0 }],
49
+ budget: 2000,
50
+ });
51
+ expect(result.oversized).toBe(false);
52
+ });
53
+ it('is oversized when the counted size is strictly greater than the budget', () => {
54
+ const result = evaluateDiffSizeGate({
55
+ files: [{ path: 'src/a.ts', additions: 2000, deletions: 1 }],
56
+ budget: 2000,
57
+ });
58
+ expect(result.oversized).toBe(true);
59
+ expect(result.countedLines).toBe(2001);
60
+ });
61
+ it('returns zero counted lines for an empty file list', () => {
62
+ const result = evaluateDiffSizeGate({ files: [], budget: 2000 });
63
+ expect(result.countedLines).toBe(0);
64
+ expect(result.oversized).toBe(false);
65
+ });
66
+ });
67
+ //# sourceMappingURL=diffSizeGate.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diffSizeGate.test.js","sourceRoot":"","sources":["../../../../../../../src/tests/units/modules/shared-kernel/entities/diffSizeGate/diffSizeGate.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=projectIdentifier.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projectIdentifier.test.d.ts","sourceRoot":"","sources":["../../../../../../../src/tests/units/modules/statistics-insights/entities/projectIdentifier/projectIdentifier.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,29 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { resolveProjectIdentifier } from '../../../../../../modules/statistics-insights/entities/projectIdentifier/projectIdentifier.js';
3
+ describe('resolveProjectIdentifier', () => {
4
+ it('resolves an SSH GitLab remote to its namespace', () => {
5
+ expect(resolveProjectIdentifier('git@gitlab.com:group/proj.git')).toBe('group/proj');
6
+ });
7
+ it('resolves an HTTPS GitLab remote to its namespace', () => {
8
+ expect(resolveProjectIdentifier('https://gitlab.com/group/proj.git')).toBe('group/proj');
9
+ });
10
+ it('preserves nested GitLab groups', () => {
11
+ expect(resolveProjectIdentifier('git@gitlab.com:group/sub/proj.git')).toBe('group/sub/proj');
12
+ });
13
+ it('resolves an SSH GitHub remote to owner/repo', () => {
14
+ expect(resolveProjectIdentifier('git@github.com:owner/repo.git')).toBe('owner/repo');
15
+ });
16
+ it('resolves an HTTPS GitHub remote without a .git suffix', () => {
17
+ expect(resolveProjectIdentifier('https://github.com/owner/repo')).toBe('owner/repo');
18
+ });
19
+ it('strips a self-hosted host', () => {
20
+ expect(resolveProjectIdentifier('git@gitlab.example.com:org/proj.git')).toBe('org/proj');
21
+ });
22
+ it('returns null for an unparseable string', () => {
23
+ expect(resolveProjectIdentifier('not-a-url')).toBeNull();
24
+ });
25
+ it('returns null for an empty string', () => {
26
+ expect(resolveProjectIdentifier('')).toBeNull();
27
+ });
28
+ });
29
+ //# sourceMappingURL=projectIdentifier.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projectIdentifier.test.js","sourceRoot":"","sources":["../../../../../../../src/tests/units/modules/statistics-insights/entities/projectIdentifier/projectIdentifier.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAE9C,OAAO,EAAE,wBAAwB,EAAE,MAAM,+EAA+E,CAAC;AAEzH,QAAQ,CAAC,0BAA0B,EAAE,GAAG,EAAE;IACxC,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;QACxD,MAAM,CAAC,wBAAwB,CAAC,+BAA+B,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACvF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;QAC1D,MAAM,CAAC,wBAAwB,CAAC,mCAAmC,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC3F,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;QACxC,MAAM,CAAC,wBAAwB,CAAC,mCAAmC,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAC/F,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,MAAM,CAAC,wBAAwB,CAAC,+BAA+B,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACvF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,MAAM,CAAC,wBAAwB,CAAC,+BAA+B,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACvF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2BAA2B,EAAE,GAAG,EAAE;QACnC,MAAM,CAAC,wBAAwB,CAAC,qCAAqC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC3F,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;QAChD,MAAM,CAAC,wBAAwB,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC3D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,CAAC,wBAAwB,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;IAClD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}