intentpatch 0.0.0-stage → 0.1.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 (243) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +452 -2
  3. package/dist/application/ports/analysis-rule.d.ts +23 -0
  4. package/dist/application/ports/analysis-rule.d.ts.map +1 -0
  5. package/dist/application/ports/analysis-rule.js +2 -0
  6. package/dist/application/ports/analysis-rule.js.map +1 -0
  7. package/dist/application/ports/change-impact-analyzer.d.ts +6 -0
  8. package/dist/application/ports/change-impact-analyzer.d.ts.map +1 -0
  9. package/dist/application/ports/change-impact-analyzer.js +2 -0
  10. package/dist/application/ports/change-impact-analyzer.js.map +1 -0
  11. package/dist/application/ports/change-source.d.ts +10 -0
  12. package/dist/application/ports/change-source.d.ts.map +1 -0
  13. package/dist/application/ports/change-source.js +2 -0
  14. package/dist/application/ports/change-source.js.map +1 -0
  15. package/dist/application/ports/code-structure-analyzer.d.ts +6 -0
  16. package/dist/application/ports/code-structure-analyzer.d.ts.map +1 -0
  17. package/dist/application/ports/code-structure-analyzer.js +2 -0
  18. package/dist/application/ports/code-structure-analyzer.js.map +1 -0
  19. package/dist/application/ports/code-structure-extractor.d.ts +33 -0
  20. package/dist/application/ports/code-structure-extractor.d.ts.map +1 -0
  21. package/dist/application/ports/code-structure-extractor.js +2 -0
  22. package/dist/application/ports/code-structure-extractor.js.map +1 -0
  23. package/dist/application/ports/file-snapshot-source.d.ts +10 -0
  24. package/dist/application/ports/file-snapshot-source.d.ts.map +1 -0
  25. package/dist/application/ports/file-snapshot-source.js +2 -0
  26. package/dist/application/ports/file-snapshot-source.js.map +1 -0
  27. package/dist/application/ports/module-reference-extractor.d.ts +13 -0
  28. package/dist/application/ports/module-reference-extractor.d.ts.map +1 -0
  29. package/dist/application/ports/module-reference-extractor.js +2 -0
  30. package/dist/application/ports/module-reference-extractor.js.map +1 -0
  31. package/dist/application/ports/project-file-source.d.ts +16 -0
  32. package/dist/application/ports/project-file-source.d.ts.map +1 -0
  33. package/dist/application/ports/project-file-source.js +2 -0
  34. package/dist/application/ports/project-file-source.js.map +1 -0
  35. package/dist/application/ports/source-symbol-extractor.d.ts +14 -0
  36. package/dist/application/ports/source-symbol-extractor.d.ts.map +1 -0
  37. package/dist/application/ports/source-symbol-extractor.js +2 -0
  38. package/dist/application/ports/source-symbol-extractor.js.map +1 -0
  39. package/dist/application/ports/symbol-change-analyzer.d.ts +6 -0
  40. package/dist/application/ports/symbol-change-analyzer.d.ts.map +1 -0
  41. package/dist/application/ports/symbol-change-analyzer.js +2 -0
  42. package/dist/application/ports/symbol-change-analyzer.js.map +1 -0
  43. package/dist/application/ports/test-change-analyzer.d.ts +6 -0
  44. package/dist/application/ports/test-change-analyzer.d.ts.map +1 -0
  45. package/dist/application/ports/test-change-analyzer.js +2 -0
  46. package/dist/application/ports/test-change-analyzer.js.map +1 -0
  47. package/dist/application/rules/change-budget-rule.d.ts +7 -0
  48. package/dist/application/rules/change-budget-rule.d.ts.map +1 -0
  49. package/dist/application/rules/change-budget-rule.js +42 -0
  50. package/dist/application/rules/change-budget-rule.js.map +1 -0
  51. package/dist/application/rules/duplicate-implementation-rule.d.ts +7 -0
  52. package/dist/application/rules/duplicate-implementation-rule.d.ts.map +1 -0
  53. package/dist/application/rules/duplicate-implementation-rule.js +20 -0
  54. package/dist/application/rules/duplicate-implementation-rule.js.map +1 -0
  55. package/dist/application/rules/expected-scope-rule.d.ts +7 -0
  56. package/dist/application/rules/expected-scope-rule.d.ts.map +1 -0
  57. package/dist/application/rules/expected-scope-rule.js +27 -0
  58. package/dist/application/rules/expected-scope-rule.js.map +1 -0
  59. package/dist/application/rules/missing-test-change-rule.d.ts +7 -0
  60. package/dist/application/rules/missing-test-change-rule.d.ts.map +1 -0
  61. package/dist/application/rules/missing-test-change-rule.js +25 -0
  62. package/dist/application/rules/missing-test-change-rule.js.map +1 -0
  63. package/dist/application/rules/package-dependency-rule.d.ts +13 -0
  64. package/dist/application/rules/package-dependency-rule.d.ts.map +1 -0
  65. package/dist/application/rules/package-dependency-rule.js +174 -0
  66. package/dist/application/rules/package-dependency-rule.js.map +1 -0
  67. package/dist/application/rules/public-api-compatibility-rule.d.ts +7 -0
  68. package/dist/application/rules/public-api-compatibility-rule.d.ts.map +1 -0
  69. package/dist/application/rules/public-api-compatibility-rule.js +92 -0
  70. package/dist/application/rules/public-api-compatibility-rule.js.map +1 -0
  71. package/dist/application/rules/public-api-removal-rule.d.ts +7 -0
  72. package/dist/application/rules/public-api-removal-rule.d.ts.map +1 -0
  73. package/dist/application/rules/public-api-removal-rule.js +45 -0
  74. package/dist/application/rules/public-api-removal-rule.js.map +1 -0
  75. package/dist/application/rules/single-implementation-abstraction-rule.d.ts +7 -0
  76. package/dist/application/rules/single-implementation-abstraction-rule.d.ts.map +1 -0
  77. package/dist/application/rules/single-implementation-abstraction-rule.js +20 -0
  78. package/dist/application/rules/single-implementation-abstraction-rule.js.map +1 -0
  79. package/dist/application/services/analyze-code-structure.d.ts +14 -0
  80. package/dist/application/services/analyze-code-structure.d.ts.map +1 -0
  81. package/dist/application/services/analyze-code-structure.js +113 -0
  82. package/dist/application/services/analyze-code-structure.js.map +1 -0
  83. package/dist/application/services/analyze-import-impact.d.ts +14 -0
  84. package/dist/application/services/analyze-import-impact.d.ts.map +1 -0
  85. package/dist/application/services/analyze-import-impact.js +142 -0
  86. package/dist/application/services/analyze-import-impact.js.map +1 -0
  87. package/dist/application/services/analyze-test-changes.d.ts +8 -0
  88. package/dist/application/services/analyze-test-changes.d.ts.map +1 -0
  89. package/dist/application/services/analyze-test-changes.js +41 -0
  90. package/dist/application/services/analyze-test-changes.js.map +1 -0
  91. package/dist/application/services/compare-source-symbols.d.ts +13 -0
  92. package/dist/application/services/compare-source-symbols.d.ts.map +1 -0
  93. package/dist/application/services/compare-source-symbols.js +103 -0
  94. package/dist/application/services/compare-source-symbols.js.map +1 -0
  95. package/dist/application/services/path-pattern.d.ts +3 -0
  96. package/dist/application/services/path-pattern.d.ts.map +1 -0
  97. package/dist/application/services/path-pattern.js +34 -0
  98. package/dist/application/services/path-pattern.js.map +1 -0
  99. package/dist/application/services/rule-engine.d.ts +9 -0
  100. package/dist/application/services/rule-engine.d.ts.map +1 -0
  101. package/dist/application/services/rule-engine.js +13 -0
  102. package/dist/application/services/rule-engine.js.map +1 -0
  103. package/dist/application/use-cases/analyze-changes.d.ts +28 -0
  104. package/dist/application/use-cases/analyze-changes.d.ts.map +1 -0
  105. package/dist/application/use-cases/analyze-changes.js +88 -0
  106. package/dist/application/use-cases/analyze-changes.js.map +1 -0
  107. package/dist/domain/change-contract.d.ts +33 -0
  108. package/dist/domain/change-contract.d.ts.map +1 -0
  109. package/dist/domain/change-contract.js +76 -0
  110. package/dist/domain/change-contract.js.map +1 -0
  111. package/dist/domain/change.d.ts +37 -0
  112. package/dist/domain/change.d.ts.map +1 -0
  113. package/dist/domain/change.js +61 -0
  114. package/dist/domain/change.js.map +1 -0
  115. package/dist/domain/code-structure.d.ts +38 -0
  116. package/dist/domain/code-structure.d.ts.map +1 -0
  117. package/dist/domain/code-structure.js +63 -0
  118. package/dist/domain/code-structure.js.map +1 -0
  119. package/dist/domain/finding.d.ts +24 -0
  120. package/dist/domain/finding.d.ts.map +1 -0
  121. package/dist/domain/finding.js +30 -0
  122. package/dist/domain/finding.js.map +1 -0
  123. package/dist/domain/impact.d.ts +45 -0
  124. package/dist/domain/impact.d.ts.map +1 -0
  125. package/dist/domain/impact.js +60 -0
  126. package/dist/domain/impact.js.map +1 -0
  127. package/dist/domain/report.d.ts +22 -0
  128. package/dist/domain/report.d.ts.map +1 -0
  129. package/dist/domain/report.js +2 -0
  130. package/dist/domain/report.js.map +1 -0
  131. package/dist/domain/symbol-change.d.ts +60 -0
  132. package/dist/domain/symbol-change.d.ts.map +1 -0
  133. package/dist/domain/symbol-change.js +79 -0
  134. package/dist/domain/symbol-change.js.map +1 -0
  135. package/dist/domain/test-change.d.ts +29 -0
  136. package/dist/domain/test-change.d.ts.map +1 -0
  137. package/dist/domain/test-change.js +35 -0
  138. package/dist/domain/test-change.js.map +1 -0
  139. package/dist/infrastructure/config/json-change-contract-loader.d.ts +6 -0
  140. package/dist/infrastructure/config/json-change-contract-loader.d.ts.map +1 -0
  141. package/dist/infrastructure/config/json-change-contract-loader.js +130 -0
  142. package/dist/infrastructure/config/json-change-contract-loader.js.map +1 -0
  143. package/dist/infrastructure/filesystem/repository-path.d.ts +3 -0
  144. package/dist/infrastructure/filesystem/repository-path.d.ts.map +1 -0
  145. package/dist/infrastructure/filesystem/repository-path.js +11 -0
  146. package/dist/infrastructure/filesystem/repository-path.js.map +1 -0
  147. package/dist/infrastructure/git/diff-parser.d.ts +3 -0
  148. package/dist/infrastructure/git/diff-parser.d.ts.map +1 -0
  149. package/dist/infrastructure/git/diff-parser.js +124 -0
  150. package/dist/infrastructure/git/diff-parser.js.map +1 -0
  151. package/dist/infrastructure/git/git-change-source.d.ts +13 -0
  152. package/dist/infrastructure/git/git-change-source.d.ts.map +1 -0
  153. package/dist/infrastructure/git/git-change-source.js +43 -0
  154. package/dist/infrastructure/git/git-change-source.js.map +1 -0
  155. package/dist/infrastructure/git/git-file-snapshot-source.d.ts +14 -0
  156. package/dist/infrastructure/git/git-file-snapshot-source.d.ts.map +1 -0
  157. package/dist/infrastructure/git/git-file-snapshot-source.js +87 -0
  158. package/dist/infrastructure/git/git-file-snapshot-source.js.map +1 -0
  159. package/dist/infrastructure/git/git-project-file-source.d.ts +16 -0
  160. package/dist/infrastructure/git/git-project-file-source.d.ts.map +1 -0
  161. package/dist/infrastructure/git/git-project-file-source.js +113 -0
  162. package/dist/infrastructure/git/git-project-file-source.js.map +1 -0
  163. package/dist/infrastructure/git/untracked-file-collector.d.ts +4 -0
  164. package/dist/infrastructure/git/untracked-file-collector.d.ts.map +1 -0
  165. package/dist/infrastructure/git/untracked-file-collector.js +52 -0
  166. package/dist/infrastructure/git/untracked-file-collector.js.map +1 -0
  167. package/dist/infrastructure/process/command-runner.d.ts +17 -0
  168. package/dist/infrastructure/process/command-runner.d.ts.map +1 -0
  169. package/dist/infrastructure/process/command-runner.js +35 -0
  170. package/dist/infrastructure/process/command-runner.js.map +1 -0
  171. package/dist/infrastructure/typescript/parse-typescript-source.d.ts +11 -0
  172. package/dist/infrastructure/typescript/parse-typescript-source.d.ts.map +1 -0
  173. package/dist/infrastructure/typescript/parse-typescript-source.js +31 -0
  174. package/dist/infrastructure/typescript/parse-typescript-source.js.map +1 -0
  175. package/dist/infrastructure/typescript/typescript-code-structure-extractor.d.ts +7 -0
  176. package/dist/infrastructure/typescript/typescript-code-structure-extractor.d.ts.map +1 -0
  177. package/dist/infrastructure/typescript/typescript-code-structure-extractor.js +80 -0
  178. package/dist/infrastructure/typescript/typescript-code-structure-extractor.js.map +1 -0
  179. package/dist/infrastructure/typescript/typescript-module-reference-extractor.d.ts +7 -0
  180. package/dist/infrastructure/typescript/typescript-module-reference-extractor.d.ts.map +1 -0
  181. package/dist/infrastructure/typescript/typescript-module-reference-extractor.js +37 -0
  182. package/dist/infrastructure/typescript/typescript-module-reference-extractor.js.map +1 -0
  183. package/dist/infrastructure/typescript/typescript-symbol-extractor.d.ts +7 -0
  184. package/dist/infrastructure/typescript/typescript-symbol-extractor.d.ts.map +1 -0
  185. package/dist/infrastructure/typescript/typescript-symbol-extractor.js +206 -0
  186. package/dist/infrastructure/typescript/typescript-symbol-extractor.js.map +1 -0
  187. package/dist/presentation/analyze-repository.d.ts +10 -0
  188. package/dist/presentation/analyze-repository.d.ts.map +1 -0
  189. package/dist/presentation/analyze-repository.js +55 -0
  190. package/dist/presentation/analyze-repository.js.map +1 -0
  191. package/dist/presentation/cli/arguments.d.ts +26 -0
  192. package/dist/presentation/cli/arguments.d.ts.map +1 -0
  193. package/dist/presentation/cli/arguments.js +120 -0
  194. package/dist/presentation/cli/arguments.js.map +1 -0
  195. package/dist/presentation/cli/failure-policy.d.ts +3 -0
  196. package/dist/presentation/cli/failure-policy.d.ts.map +1 -0
  197. package/dist/presentation/cli/failure-policy.js +5 -0
  198. package/dist/presentation/cli/failure-policy.js.map +1 -0
  199. package/dist/presentation/cli/main.d.ts +3 -0
  200. package/dist/presentation/cli/main.d.ts.map +1 -0
  201. package/dist/presentation/cli/main.js +71 -0
  202. package/dist/presentation/cli/main.js.map +1 -0
  203. package/dist/presentation/cli/report-file-writer.d.ts +3 -0
  204. package/dist/presentation/cli/report-file-writer.d.ts.map +1 -0
  205. package/dist/presentation/cli/report-file-writer.js +9 -0
  206. package/dist/presentation/cli/report-file-writer.js.map +1 -0
  207. package/dist/presentation/cli/report-formatter.d.ts +5 -0
  208. package/dist/presentation/cli/report-formatter.d.ts.map +1 -0
  209. package/dist/presentation/cli/report-formatter.js +14 -0
  210. package/dist/presentation/cli/report-formatter.js.map +1 -0
  211. package/dist/presentation/cli/text-report.d.ts +3 -0
  212. package/dist/presentation/cli/text-report.d.ts.map +1 -0
  213. package/dist/presentation/cli/text-report.js +151 -0
  214. package/dist/presentation/cli/text-report.js.map +1 -0
  215. package/dist/presentation/github/action-inputs.d.ts +14 -0
  216. package/dist/presentation/github/action-inputs.d.ts.map +1 -0
  217. package/dist/presentation/github/action-inputs.js +24 -0
  218. package/dist/presentation/github/action-inputs.js.map +1 -0
  219. package/dist/presentation/github/action-main.d.ts +3 -0
  220. package/dist/presentation/github/action-main.d.ts.map +1 -0
  221. package/dist/presentation/github/action-main.js +20 -0
  222. package/dist/presentation/github/action-main.js.map +1 -0
  223. package/dist/presentation/github/action-runtime.d.ts +22 -0
  224. package/dist/presentation/github/action-runtime.d.ts.map +1 -0
  225. package/dist/presentation/github/action-runtime.js +58 -0
  226. package/dist/presentation/github/action-runtime.js.map +1 -0
  227. package/dist/presentation/github/comparison.d.ts +11 -0
  228. package/dist/presentation/github/comparison.d.ts.map +1 -0
  229. package/dist/presentation/github/comparison.js +35 -0
  230. package/dist/presentation/github/comparison.js.map +1 -0
  231. package/dist/presentation/github/markdown-summary.d.ts +4 -0
  232. package/dist/presentation/github/markdown-summary.d.ts.map +1 -0
  233. package/dist/presentation/github/markdown-summary.js +47 -0
  234. package/dist/presentation/github/markdown-summary.js.map +1 -0
  235. package/dist/presentation/github/run-action.d.ts +7 -0
  236. package/dist/presentation/github/run-action.d.ts.map +1 -0
  237. package/dist/presentation/github/run-action.js +81 -0
  238. package/dist/presentation/github/run-action.js.map +1 -0
  239. package/dist/presentation/html/html-report.d.ts +4 -0
  240. package/dist/presentation/html/html-report.d.ts.map +1 -0
  241. package/dist/presentation/html/html-report.js +362 -0
  242. package/dist/presentation/html/html-report.js.map +1 -0
  243. package/package.json +52 -4
@@ -0,0 +1,45 @@
1
+ export interface ModuleDependency {
2
+ readonly importer: string;
3
+ readonly imported: string;
4
+ }
5
+ export interface ImpactedFile {
6
+ readonly path: string;
7
+ readonly distance: number;
8
+ readonly changedModules: readonly string[];
9
+ }
10
+ export interface UnresolvedModuleReference {
11
+ readonly importer: string;
12
+ readonly specifier: string;
13
+ }
14
+ export interface ImpactAnalysisIssue {
15
+ readonly path: string;
16
+ readonly reason: string;
17
+ }
18
+ export interface ImpactSummary {
19
+ readonly sourceFiles: number;
20
+ readonly changedModules: number;
21
+ readonly dependencies: number;
22
+ readonly directDependents: number;
23
+ readonly transitiveDependents: number;
24
+ readonly unresolvedReferences: number;
25
+ readonly filesUnavailable: number;
26
+ }
27
+ export interface ImpactAnalysis {
28
+ readonly changedModules: readonly string[];
29
+ readonly dependencies: readonly ModuleDependency[];
30
+ readonly impactedFiles: readonly ImpactedFile[];
31
+ readonly unresolvedReferences: readonly UnresolvedModuleReference[];
32
+ readonly issues: readonly ImpactAnalysisIssue[];
33
+ readonly summary: ImpactSummary;
34
+ }
35
+ export interface CreateImpactAnalysisInput {
36
+ readonly changedModules: readonly string[];
37
+ readonly dependencies: readonly ModuleDependency[];
38
+ readonly impactedFiles: readonly ImpactedFile[];
39
+ readonly unresolvedReferences?: readonly UnresolvedModuleReference[];
40
+ readonly issues?: readonly ImpactAnalysisIssue[];
41
+ readonly sourceFiles: number;
42
+ }
43
+ /** 그래프 결과를 정렬·동결해 실행 순서와 무관한 보고서를 만든다. */
44
+ export declare function createImpactAnalysis(input: CreateImpactAnalysisInput): ImpactAnalysis;
45
+ //# sourceMappingURL=impact.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"impact.d.ts","sourceRoot":"","sources":["../../src/domain/impact.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5C;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;CACnC;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3C,QAAQ,CAAC,YAAY,EAAE,SAAS,gBAAgB,EAAE,CAAC;IACnD,QAAQ,CAAC,aAAa,EAAE,SAAS,YAAY,EAAE,CAAC;IAChD,QAAQ,CAAC,oBAAoB,EAAE,SAAS,yBAAyB,EAAE,CAAC;IACpE,QAAQ,CAAC,MAAM,EAAE,SAAS,mBAAmB,EAAE,CAAC;IAChD,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;CACjC;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3C,QAAQ,CAAC,YAAY,EAAE,SAAS,gBAAgB,EAAE,CAAC;IACnD,QAAQ,CAAC,aAAa,EAAE,SAAS,YAAY,EAAE,CAAC;IAChD,QAAQ,CAAC,oBAAoB,CAAC,EAAE,SAAS,yBAAyB,EAAE,CAAC;IACrE,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,mBAAmB,EAAE,CAAC;IACjD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED,0CAA0C;AAC1C,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,yBAAyB,GAAG,cAAc,CAyBrF"}
@@ -0,0 +1,60 @@
1
+ /** 그래프 결과를 정렬·동결해 실행 순서와 무관한 보고서를 만든다. */
2
+ export function createImpactAnalysis(input) {
3
+ const changedModules = uniqueSorted(input.changedModules);
4
+ const dependencies = uniqueDependencies(input.dependencies);
5
+ const impactedFiles = uniqueImpactedFiles(input.impactedFiles);
6
+ const unresolvedReferences = uniqueUnresolvedReferences(input.unresolvedReferences ?? []);
7
+ const issues = [...(input.issues ?? [])]
8
+ .map((issue) => Object.freeze({ ...issue }))
9
+ .sort((left, right) => left.path.localeCompare(right.path));
10
+ return Object.freeze({
11
+ changedModules: Object.freeze(changedModules),
12
+ dependencies: Object.freeze(dependencies),
13
+ impactedFiles: Object.freeze(impactedFiles),
14
+ unresolvedReferences: Object.freeze(unresolvedReferences),
15
+ issues: Object.freeze(issues),
16
+ summary: Object.freeze({
17
+ sourceFiles: input.sourceFiles,
18
+ changedModules: changedModules.length,
19
+ dependencies: dependencies.length,
20
+ directDependents: impactedFiles.filter((file) => file.distance === 1).length,
21
+ transitiveDependents: impactedFiles.filter((file) => file.distance > 1).length,
22
+ unresolvedReferences: unresolvedReferences.length,
23
+ filesUnavailable: issues.length,
24
+ }),
25
+ });
26
+ }
27
+ function uniqueSorted(values) {
28
+ return [...new Set(values)].sort((left, right) => left.localeCompare(right));
29
+ }
30
+ function uniqueDependencies(values) {
31
+ const unique = new Map();
32
+ for (const value of values) {
33
+ unique.set(`${value.importer}\0${value.imported}`, Object.freeze({ importer: value.importer, imported: value.imported }));
34
+ }
35
+ return [...unique.values()].sort((left, right) => left.importer.localeCompare(right.importer) || left.imported.localeCompare(right.imported));
36
+ }
37
+ function uniqueImpactedFiles(values) {
38
+ const unique = new Map();
39
+ for (const value of values) {
40
+ if (!Number.isSafeInteger(value.distance) || value.distance < 1) {
41
+ throw new Error(`Impact distance must be a positive integer: ${value.path}`);
42
+ }
43
+ if (unique.has(value.path)) {
44
+ throw new Error(`Duplicate impacted file: ${value.path}`);
45
+ }
46
+ unique.set(value.path, Object.freeze({
47
+ ...value,
48
+ changedModules: Object.freeze(uniqueSorted(value.changedModules)),
49
+ }));
50
+ }
51
+ return [...unique.values()].sort((left, right) => left.distance - right.distance || left.path.localeCompare(right.path));
52
+ }
53
+ function uniqueUnresolvedReferences(values) {
54
+ const unique = new Map();
55
+ for (const value of values) {
56
+ unique.set(`${value.importer}\0${value.specifier}`, Object.freeze({ importer: value.importer, specifier: value.specifier }));
57
+ }
58
+ return [...unique.values()].sort((left, right) => left.importer.localeCompare(right.importer) || left.specifier.localeCompare(right.specifier));
59
+ }
60
+ //# sourceMappingURL=impact.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"impact.js","sourceRoot":"","sources":["../../src/domain/impact.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import type { ChangeSet } from "./change.js";
2
+ import type { ChangeContract } from "./change-contract.js";
3
+ import type { CodeStructureAnalysis } from "./code-structure.js";
4
+ import type { FindingSet } from "./finding.js";
5
+ import type { ImpactAnalysis } from "./impact.js";
6
+ import type { SymbolChangeSet } from "./symbol-change.js";
7
+ import type { TestChangeAnalysis } from "./test-change.js";
8
+ export interface AnalysisTarget {
9
+ readonly baseRef: string;
10
+ readonly headRef?: string;
11
+ }
12
+ export interface ChangeReport {
13
+ readonly target: AnalysisTarget;
14
+ readonly contract?: ChangeContract;
15
+ readonly changes: ChangeSet;
16
+ readonly findings: FindingSet;
17
+ readonly symbolChanges: SymbolChangeSet;
18
+ readonly codeStructure: CodeStructureAnalysis;
19
+ readonly impact: ImpactAnalysis;
20
+ readonly testChanges: TestChangeAnalysis;
21
+ }
22
+ //# sourceMappingURL=report.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/domain/report.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAE3D,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,QAAQ,CAAC,QAAQ,CAAC,EAAE,cAAc,CAAC;IACnC,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,UAAU,CAAC;IAC9B,QAAQ,CAAC,aAAa,EAAE,eAAe,CAAC;IACxC,QAAQ,CAAC,aAAa,EAAE,qBAAqB,CAAC;IAC9C,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,QAAQ,CAAC,WAAW,EAAE,kBAAkB,CAAC;CAC1C"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/domain/report.ts"],"names":[],"mappings":""}
@@ -0,0 +1,60 @@
1
+ export declare const sourceSymbolKinds: readonly ["function", "class", "interface", "type-alias", "re-export"];
2
+ export declare const symbolChangeKinds: readonly ["added", "modified", "deleted"];
3
+ export type SourceSymbolKind = (typeof sourceSymbolKinds)[number];
4
+ export type SymbolChangeKind = (typeof symbolChangeKinds)[number];
5
+ export interface FunctionPublicApi {
6
+ readonly kind: "function";
7
+ readonly signatures: readonly string[];
8
+ }
9
+ export interface InterfacePublicApiMember {
10
+ readonly name: string;
11
+ readonly memberKind: "property" | "method";
12
+ readonly optional: boolean;
13
+ readonly signature: string;
14
+ }
15
+ export interface InterfacePublicApi {
16
+ readonly kind: "interface";
17
+ readonly extendsTypes: readonly string[];
18
+ readonly members: readonly InterfacePublicApiMember[];
19
+ }
20
+ export type PublicApi = FunctionPublicApi | InterfacePublicApi;
21
+ /** 파서가 추출한 심볼의 비교용 표현이다. fingerprint는 보고서에 노출하지 않는다. */
22
+ export interface SourceSymbol {
23
+ readonly name: string;
24
+ readonly kind: SourceSymbolKind;
25
+ readonly fingerprint: string;
26
+ readonly line: number;
27
+ /** 언어 어댑터가 공개 여부를 판단할 수 없으면 undefined로 남긴다. */
28
+ readonly exported?: boolean;
29
+ /** 구현 본문을 제외한 공개 계약이다. 지원하지 않는 심볼 종류에는 존재하지 않는다. */
30
+ readonly publicApi?: PublicApi;
31
+ }
32
+ export interface SymbolChange {
33
+ readonly path: string;
34
+ readonly name: string;
35
+ readonly symbolKind: SourceSymbolKind;
36
+ readonly changeKind: SymbolChangeKind;
37
+ readonly beforeLine?: number;
38
+ readonly afterLine?: number;
39
+ readonly beforeExported?: boolean;
40
+ readonly afterExported?: boolean;
41
+ readonly beforePublicApi?: PublicApi;
42
+ readonly afterPublicApi?: PublicApi;
43
+ }
44
+ export interface SymbolAnalysisIssue {
45
+ readonly path: string;
46
+ readonly reason: string;
47
+ }
48
+ export interface SymbolChangeSummary {
49
+ readonly total: number;
50
+ readonly filesAnalyzed: number;
51
+ readonly filesUnavailable: number;
52
+ readonly byChangeKind: Readonly<Record<SymbolChangeKind, number>>;
53
+ }
54
+ export interface SymbolChangeSet {
55
+ readonly changes: readonly SymbolChange[];
56
+ readonly issues: readonly SymbolAnalysisIssue[];
57
+ readonly summary: SymbolChangeSummary;
58
+ }
59
+ export declare function createSymbolChangeSet(changes: readonly SymbolChange[], issues?: readonly SymbolAnalysisIssue[], filesAnalyzed?: number): SymbolChangeSet;
60
+ //# sourceMappingURL=symbol-change.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"symbol-change.d.ts","sourceRoot":"","sources":["../../src/domain/symbol-change.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,79 @@
1
+ export const sourceSymbolKinds = [
2
+ "function",
3
+ "class",
4
+ "interface",
5
+ "type-alias",
6
+ "re-export",
7
+ ];
8
+ export const symbolChangeKinds = ["added", "modified", "deleted"];
9
+ const changeKindRank = {
10
+ added: 0,
11
+ modified: 1,
12
+ deleted: 2,
13
+ };
14
+ export function createSymbolChangeSet(changes, issues = [], filesAnalyzed = 0) {
15
+ assertUniqueChanges(changes);
16
+ const sortedChanges = [...changes].map(freezeChange).sort(compareChanges);
17
+ const sortedIssues = [...issues]
18
+ .map((issue) => Object.freeze({ ...issue }))
19
+ .sort((left, right) => left.path.localeCompare(right.path));
20
+ const byChangeKind = {
21
+ added: 0,
22
+ modified: 0,
23
+ deleted: 0,
24
+ };
25
+ for (const change of sortedChanges) {
26
+ byChangeKind[change.changeKind] += 1;
27
+ }
28
+ return Object.freeze({
29
+ changes: Object.freeze(sortedChanges),
30
+ issues: Object.freeze(sortedIssues),
31
+ summary: Object.freeze({
32
+ total: sortedChanges.length,
33
+ filesAnalyzed,
34
+ filesUnavailable: sortedIssues.length,
35
+ byChangeKind: Object.freeze(byChangeKind),
36
+ }),
37
+ });
38
+ }
39
+ function freezeChange(change) {
40
+ return Object.freeze({
41
+ ...change,
42
+ ...(change.beforePublicApi === undefined
43
+ ? {}
44
+ : { beforePublicApi: freezePublicApi(change.beforePublicApi) }),
45
+ ...(change.afterPublicApi === undefined
46
+ ? {}
47
+ : { afterPublicApi: freezePublicApi(change.afterPublicApi) }),
48
+ });
49
+ }
50
+ function freezePublicApi(publicApi) {
51
+ if (publicApi.kind === "function") {
52
+ return Object.freeze({
53
+ kind: publicApi.kind,
54
+ signatures: Object.freeze([...publicApi.signatures]),
55
+ });
56
+ }
57
+ return Object.freeze({
58
+ kind: publicApi.kind,
59
+ extendsTypes: Object.freeze([...publicApi.extendsTypes]),
60
+ members: Object.freeze(publicApi.members.map((member) => Object.freeze({ ...member }))),
61
+ });
62
+ }
63
+ function compareChanges(left, right) {
64
+ return (left.path.localeCompare(right.path) ||
65
+ changeKindRank[left.changeKind] - changeKindRank[right.changeKind] ||
66
+ left.symbolKind.localeCompare(right.symbolKind) ||
67
+ left.name.localeCompare(right.name));
68
+ }
69
+ function assertUniqueChanges(changes) {
70
+ const identities = new Set();
71
+ for (const change of changes) {
72
+ const identity = [change.path, change.symbolKind, change.name].join("\0");
73
+ if (identities.has(identity)) {
74
+ throw new Error(`Duplicate symbol change: ${change.path} ${change.symbolKind} ${change.name}`);
75
+ }
76
+ identities.add(identity);
77
+ }
78
+ }
79
+ //# sourceMappingURL=symbol-change.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"symbol-change.js","sourceRoot":"","sources":["../../src/domain/symbol-change.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import type { FileChangeKind } from "./change.js";
2
+ export interface TestFileChange {
3
+ readonly path: string;
4
+ readonly changeKind: FileChangeKind;
5
+ }
6
+ export interface SourceTestCoverage {
7
+ readonly sourcePath: string;
8
+ readonly sourceChangeKind: FileChangeKind;
9
+ readonly matchingTests: readonly string[];
10
+ }
11
+ export interface TestChangeSummary {
12
+ readonly testsChanged: number;
13
+ readonly testsAdded: number;
14
+ readonly testsDeleted: number;
15
+ readonly sourceFilesChecked: number;
16
+ readonly sourceFilesWithoutTestChanges: number;
17
+ }
18
+ export interface TestChangeAnalysis {
19
+ readonly testFiles: readonly TestFileChange[];
20
+ readonly sourceCoverage: readonly SourceTestCoverage[];
21
+ readonly summary: TestChangeSummary;
22
+ }
23
+ export interface CreateTestChangeAnalysisInput {
24
+ readonly testFiles: readonly TestFileChange[];
25
+ readonly sourceCoverage: readonly SourceTestCoverage[];
26
+ }
27
+ /** 테스트 변경 사실을 정렬·동결하고 소스별 동반 변경 여부를 집계한다. */
28
+ export declare function createTestChangeAnalysis(input: CreateTestChangeAnalysisInput): TestChangeAnalysis;
29
+ //# sourceMappingURL=test-change.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-change.d.ts","sourceRoot":"","sources":["../../src/domain/test-change.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,cAAc,CAAC;CACrC;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,gBAAgB,EAAE,cAAc,CAAC;IAC1C,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;CAC3C;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,6BAA6B,EAAE,MAAM,CAAC;CAChD;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,SAAS,EAAE,SAAS,cAAc,EAAE,CAAC;IAC9C,QAAQ,CAAC,cAAc,EAAE,SAAS,kBAAkB,EAAE,CAAC;IACvD,QAAQ,CAAC,OAAO,EAAE,iBAAiB,CAAC;CACrC;AAED,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,SAAS,EAAE,SAAS,cAAc,EAAE,CAAC;IAC9C,QAAQ,CAAC,cAAc,EAAE,SAAS,kBAAkB,EAAE,CAAC;CACxD;AAED,6CAA6C;AAC7C,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,6BAA6B,GAAG,kBAAkB,CAqCjG"}
@@ -0,0 +1,35 @@
1
+ /** 테스트 변경 사실을 정렬·동결하고 소스별 동반 변경 여부를 집계한다. */
2
+ export function createTestChangeAnalysis(input) {
3
+ assertUniquePaths(input.testFiles.map((file) => file.path), "test file");
4
+ assertUniquePaths(input.sourceCoverage.map((coverage) => coverage.sourcePath), "source file");
5
+ const testFiles = input.testFiles
6
+ .map((file) => Object.freeze({ ...file }))
7
+ .sort((left, right) => left.path.localeCompare(right.path));
8
+ const sourceCoverage = input.sourceCoverage
9
+ .map((coverage) => Object.freeze({
10
+ ...coverage,
11
+ matchingTests: Object.freeze([...new Set(coverage.matchingTests)].sort((left, right) => left.localeCompare(right))),
12
+ }))
13
+ .sort((left, right) => left.sourcePath.localeCompare(right.sourcePath));
14
+ return Object.freeze({
15
+ testFiles: Object.freeze(testFiles),
16
+ sourceCoverage: Object.freeze(sourceCoverage),
17
+ summary: Object.freeze({
18
+ testsChanged: testFiles.length,
19
+ testsAdded: testFiles.filter((file) => file.changeKind === "added").length,
20
+ testsDeleted: testFiles.filter((file) => file.changeKind === "deleted").length,
21
+ sourceFilesChecked: sourceCoverage.length,
22
+ sourceFilesWithoutTestChanges: sourceCoverage.filter((coverage) => coverage.matchingTests.length === 0).length,
23
+ }),
24
+ });
25
+ }
26
+ function assertUniquePaths(paths, description) {
27
+ const unique = new Set();
28
+ for (const path of paths) {
29
+ if (unique.has(path)) {
30
+ throw new Error(`Duplicate ${description}: ${path}`);
31
+ }
32
+ unique.add(path);
33
+ }
34
+ }
35
+ //# sourceMappingURL=test-change.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-change.js","sourceRoot":"","sources":["../../src/domain/test-change.ts"],"names":[],"mappings":"AAgCA,6CAA6C;AAC7C,MAAM,UAAU,wBAAwB,CAAC,KAAoC;IAC3E,iBAAiB,CACf,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EACxC,WAAW,CACZ,CAAC;IACF,iBAAiB,CACf,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,EAC3D,aAAa,CACd,CAAC;IAEF,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS;SAC9B,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC;SACzC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;IAC9D,MAAM,cAAc,GAAG,KAAK,CAAC,cAAc;SACxC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAChB,MAAM,CAAC,MAAM,CAAC;QACZ,GAAG,QAAQ;QACX,aAAa,EAAE,MAAM,CAAC,MAAM,CAC1B,CAAC,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CACtF;KACF,CAAC,CACH;SACA,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC;IAE1E,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC;QACnC,cAAc,EAAE,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC;QAC7C,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC;YACrB,YAAY,EAAE,SAAS,CAAC,MAAM;YAC9B,UAAU,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,KAAK,OAAO,CAAC,CAAC,MAAM;YAC1E,YAAY,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,MAAM;YAC9E,kBAAkB,EAAE,cAAc,CAAC,MAAM;YACzC,6BAA6B,EAAE,cAAc,CAAC,MAAM,CAClD,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC,MAAM,KAAK,CAAC,CAClD,CAAC,MAAM;SACT,CAAC;KACH,CAAC,CAAC;AACL,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAwB,EAAE,WAAmB;IACtE,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAC;IACjC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CAAC,aAAa,WAAW,KAAK,IAAI,EAAE,CAAC,CAAC;QACvD,CAAC;QACD,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACnB,CAAC;AACH,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { type ChangeContract } from "../../domain/change-contract.js";
2
+ /** JSON 설정을 엄격하게 검증하고 ChangeContract 도메인 모델로 변환한다. */
3
+ export declare class JsonChangeContractLoader {
4
+ load(workingDirectory: string, configurationPath?: string): Promise<ChangeContract | undefined>;
5
+ }
6
+ //# sourceMappingURL=json-change-contract-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json-change-contract-loader.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/config/json-change-contract-loader.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,cAAc,EAGpB,MAAM,iCAAiC,CAAC;AAOzC,sDAAsD;AACtD,qBAAa,wBAAwB;IACtB,IAAI,CACf,gBAAgB,EAAE,MAAM,EACxB,iBAAiB,CAAC,EAAE,MAAM,GACzB,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC;CAuBvC"}
@@ -0,0 +1,130 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { isAbsolute, resolve } from "node:path";
3
+ import { createChangeContract, } from "../../domain/change-contract.js";
4
+ const defaultConfigurationFile = ".intentpatch.json";
5
+ const rootFields = new Set(["intent", "scope", "tests"]);
6
+ const scopeFields = new Set(["include", "allow", "maxFiles", "maxLines"]);
7
+ const testFields = new Set(["requireFor", "include", "exclude"]);
8
+ /** JSON 설정을 엄격하게 검증하고 ChangeContract 도메인 모델로 변환한다. */
9
+ export class JsonChangeContractLoader {
10
+ async load(workingDirectory, configurationPath) {
11
+ const path = resolveConfigurationPath(workingDirectory, configurationPath);
12
+ let content;
13
+ try {
14
+ content = await readFile(path, "utf8");
15
+ }
16
+ catch (error) {
17
+ if (isFileNotFound(error) && configurationPath === undefined) {
18
+ return undefined;
19
+ }
20
+ if (isFileNotFound(error)) {
21
+ throw new Error(`Change contract file not found: ${path}`, { cause: error });
22
+ }
23
+ throw error;
24
+ }
25
+ try {
26
+ return createChangeContract(parseConfiguration(content));
27
+ }
28
+ catch (error) {
29
+ const reason = error instanceof Error ? error.message : String(error);
30
+ throw new Error(`Invalid change contract at ${path}: ${reason}`, { cause: error });
31
+ }
32
+ }
33
+ }
34
+ function resolveConfigurationPath(workingDirectory, configurationPath) {
35
+ if (configurationPath === undefined) {
36
+ return resolve(workingDirectory, defaultConfigurationFile);
37
+ }
38
+ return isAbsolute(configurationPath)
39
+ ? configurationPath
40
+ : resolve(workingDirectory, configurationPath);
41
+ }
42
+ function parseConfiguration(content) {
43
+ let value;
44
+ try {
45
+ value = JSON.parse(content);
46
+ }
47
+ catch {
48
+ throw new Error("The file is not valid JSON.");
49
+ }
50
+ if (!isRecord(value)) {
51
+ throw new Error("The root value must be a JSON object.");
52
+ }
53
+ assertKnownFields(value, rootFields, "root");
54
+ const intent = optionalString(value.intent, "intent");
55
+ const scopeValue = value.scope;
56
+ if (scopeValue !== undefined && !isRecord(scopeValue)) {
57
+ throw new Error("scope must be a JSON object.");
58
+ }
59
+ const scope = scopeValue ?? {};
60
+ assertKnownFields(scope, scopeFields, "scope");
61
+ const testsValue = value.tests;
62
+ if (testsValue !== undefined && !isRecord(testsValue)) {
63
+ throw new Error("tests must be a JSON object.");
64
+ }
65
+ if (testsValue !== undefined) {
66
+ assertKnownFields(testsValue, testFields, "tests");
67
+ }
68
+ return {
69
+ ...(intent === undefined ? {} : { intent }),
70
+ scope: {
71
+ include: optionalStringArray(scope.include, "scope.include"),
72
+ allow: optionalStringArray(scope.allow, "scope.allow"),
73
+ ...(scope.maxFiles === undefined
74
+ ? {}
75
+ : { maxFiles: requiredNumber(scope.maxFiles, "scope.maxFiles") }),
76
+ ...(scope.maxLines === undefined
77
+ ? {}
78
+ : { maxLines: requiredNumber(scope.maxLines, "scope.maxLines") }),
79
+ },
80
+ ...(testsValue === undefined
81
+ ? {}
82
+ : {
83
+ tests: {
84
+ requireFor: optionalStringArray(testsValue.requireFor, "tests.requireFor"),
85
+ include: optionalStringArray(testsValue.include, "tests.include"),
86
+ exclude: optionalStringArray(testsValue.exclude, "tests.exclude"),
87
+ },
88
+ }),
89
+ };
90
+ }
91
+ function assertKnownFields(value, knownFields, location) {
92
+ const unknownField = Object.keys(value).find((field) => !knownFields.has(field));
93
+ if (unknownField !== undefined) {
94
+ throw new Error(`Unknown ${location} field: ${unknownField}`);
95
+ }
96
+ }
97
+ function optionalString(value, field) {
98
+ if (value === undefined) {
99
+ return undefined;
100
+ }
101
+ if (typeof value !== "string") {
102
+ throw new Error(`${field} must be a string.`);
103
+ }
104
+ return value;
105
+ }
106
+ function optionalStringArray(value, field) {
107
+ if (value === undefined) {
108
+ return [];
109
+ }
110
+ if (!Array.isArray(value) || !value.every((item) => typeof item === "string")) {
111
+ throw new Error(`${field} must be an array of strings.`);
112
+ }
113
+ return value;
114
+ }
115
+ function requiredNumber(value, field) {
116
+ if (typeof value !== "number") {
117
+ throw new Error(`${field} must be a number.`);
118
+ }
119
+ return value;
120
+ }
121
+ function isRecord(value) {
122
+ return typeof value === "object" && value !== null && !Array.isArray(value);
123
+ }
124
+ function isFileNotFound(error) {
125
+ return (typeof error === "object" &&
126
+ error !== null &&
127
+ "code" in error &&
128
+ error.code === "ENOENT");
129
+ }
130
+ //# sourceMappingURL=json-change-contract-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json-change-contract-loader.js","sourceRoot":"","sources":["../../../src/infrastructure/config/json-change-contract-loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ /** 저장소 상대 경로가 상위 디렉터리로 탈출하지 않도록 검증하고 절대 경로로 바꾼다. */
2
+ export declare function resolveRepositoryPath(repositoryRoot: string, path: string): string;
3
+ //# sourceMappingURL=repository-path.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repository-path.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/filesystem/repository-path.ts"],"names":[],"mappings":"AAEA,oDAAoD;AACpD,wBAAgB,qBAAqB,CAAC,cAAc,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CASlF"}
@@ -0,0 +1,11 @@
1
+ import { isAbsolute, relative, resolve, sep } from "node:path";
2
+ /** 저장소 상대 경로가 상위 디렉터리로 탈출하지 않도록 검증하고 절대 경로로 바꾼다. */
3
+ export function resolveRepositoryPath(repositoryRoot, path) {
4
+ const absolutePath = resolve(repositoryRoot, path);
5
+ const relativePath = relative(repositoryRoot, absolutePath);
6
+ if (relativePath === ".." || relativePath.startsWith(`..${sep}`) || isAbsolute(relativePath)) {
7
+ throw new Error(`Path is outside the repository: ${path}`);
8
+ }
9
+ return absolutePath;
10
+ }
11
+ //# sourceMappingURL=repository-path.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repository-path.js","sourceRoot":"","sources":["../../../src/infrastructure/filesystem/repository-path.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAE/D,oDAAoD;AACpD,MAAM,UAAU,qBAAqB,CAAC,cAAsB,EAAE,IAAY;IACxE,MAAM,YAAY,GAAG,OAAO,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;IACnD,MAAM,YAAY,GAAG,QAAQ,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC;IAE5D,IAAI,YAAY,KAAK,IAAI,IAAI,YAAY,CAAC,UAAU,CAAC,KAAK,GAAG,EAAE,CAAC,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC7F,MAAM,IAAI,KAAK,CAAC,mCAAmC,IAAI,EAAE,CAAC,CAAC;IAC7D,CAAC;IAED,OAAO,YAAY,CAAC;AACtB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { FileChange } from "../../domain/change.js";
2
+ export declare function parseGitDiff(nameStatusOutput: string, numStatOutput: string): FileChange[];
3
+ //# sourceMappingURL=diff-parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff-parser.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/git/diff-parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAA6B,MAAM,wBAAwB,CAAC;AAcpF,wBAAgB,YAAY,CAAC,gBAAgB,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,UAAU,EAAE,CAkC1F"}