intentpatch 0.1.0 → 0.2.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 (45) hide show
  1. package/README.ko.md +488 -0
  2. package/README.md +215 -211
  3. package/dist/application/ports/module-alias-resolver.d.ts +11 -0
  4. package/dist/application/ports/module-alias-resolver.d.ts.map +1 -0
  5. package/dist/application/ports/module-alias-resolver.js +2 -0
  6. package/dist/application/ports/module-alias-resolver.js.map +1 -0
  7. package/dist/application/ports/package-lock-parser.d.ts +20 -0
  8. package/dist/application/ports/package-lock-parser.d.ts.map +1 -0
  9. package/dist/application/ports/package-lock-parser.js +2 -0
  10. package/dist/application/ports/package-lock-parser.js.map +1 -0
  11. package/dist/application/rules/npm-lockfile-rule.d.ts +12 -0
  12. package/dist/application/rules/npm-lockfile-rule.d.ts.map +1 -0
  13. package/dist/application/rules/npm-lockfile-rule.js +109 -0
  14. package/dist/application/rules/npm-lockfile-rule.js.map +1 -0
  15. package/dist/application/rules/npm-workspace-dependency-rule.d.ts +10 -0
  16. package/dist/application/rules/npm-workspace-dependency-rule.d.ts.map +1 -0
  17. package/dist/application/rules/npm-workspace-dependency-rule.js +155 -0
  18. package/dist/application/rules/npm-workspace-dependency-rule.js.map +1 -0
  19. package/dist/application/rules/package-dependency-rule.d.ts +4 -3
  20. package/dist/application/rules/package-dependency-rule.d.ts.map +1 -1
  21. package/dist/application/rules/package-dependency-rule.js +33 -28
  22. package/dist/application/rules/package-dependency-rule.js.map +1 -1
  23. package/dist/application/services/analyze-import-impact.d.ts +3 -1
  24. package/dist/application/services/analyze-import-impact.d.ts.map +1 -1
  25. package/dist/application/services/analyze-import-impact.js +12 -7
  26. package/dist/application/services/analyze-import-impact.js.map +1 -1
  27. package/dist/infrastructure/git/git-file-snapshot-source.d.ts.map +1 -1
  28. package/dist/infrastructure/git/git-file-snapshot-source.js +4 -2
  29. package/dist/infrastructure/git/git-file-snapshot-source.js.map +1 -1
  30. package/dist/infrastructure/npm/npm-package-lock-parser.d.ts +6 -0
  31. package/dist/infrastructure/npm/npm-package-lock-parser.d.ts.map +1 -0
  32. package/dist/infrastructure/npm/npm-package-lock-parser.js +93 -0
  33. package/dist/infrastructure/npm/npm-package-lock-parser.js.map +1 -0
  34. package/dist/infrastructure/typescript/typescript-config-loader.d.ts +17 -0
  35. package/dist/infrastructure/typescript/typescript-config-loader.d.ts.map +1 -0
  36. package/dist/infrastructure/typescript/typescript-config-loader.js +99 -0
  37. package/dist/infrastructure/typescript/typescript-config-loader.js.map +1 -0
  38. package/dist/infrastructure/typescript/typescript-module-alias-resolver.d.ts +10 -0
  39. package/dist/infrastructure/typescript/typescript-module-alias-resolver.d.ts.map +1 -0
  40. package/dist/infrastructure/typescript/typescript-module-alias-resolver.js +78 -0
  41. package/dist/infrastructure/typescript/typescript-module-alias-resolver.js.map +1 -0
  42. package/dist/presentation/analyze-repository.d.ts.map +1 -1
  43. package/dist/presentation/analyze-repository.js +7 -3
  44. package/dist/presentation/analyze-repository.js.map +1 -1
  45. package/package.json +8 -3
@@ -0,0 +1 @@
1
+ {"version":3,"file":"module-alias-resolver.d.ts","sourceRoot":"","sources":["../../../src/application/ports/module-alias-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAE7D,oDAAoD;AACpD,MAAM,WAAW,mBAAmB;IAClC,OAAO,CACL,MAAM,EAAE,cAAc,EACtB,eAAe,EAAE,SAAS,MAAM,EAAE,EAClC,WAAW,EAAE,WAAW,CAAC,MAAM,CAAC,GAC/B,OAAO,CAAC,2BAA2B,CAAC,CAAC;CACzC;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,MAAM,EAAE,SAAS,mBAAmB,EAAE,CAAC;IAChD,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CAClE"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=module-alias-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"module-alias-resolver.js","sourceRoot":"","sources":["../../../src/application/ports/module-alias-resolver.ts"],"names":[],"mappings":""}
@@ -0,0 +1,20 @@
1
+ /** npm lockfile의 설치 위치를 기준으로 비교할 수 있는 패키지 정보다. */
2
+ export interface LockedPackage {
3
+ readonly path: string;
4
+ readonly name: string;
5
+ readonly version: string;
6
+ readonly rootDirect: boolean;
7
+ }
8
+ export type PackageLockParseResult = Readonly<{
9
+ ok: true;
10
+ packages: ReadonlyMap<string, LockedPackage>;
11
+ }> | Readonly<{
12
+ ok: false;
13
+ kind: "invalid" | "unsupported";
14
+ reason: string;
15
+ }>;
16
+ /** 패키지 매니저의 파일 형식을 분석 규칙에서 분리하는 입력 포트다. */
17
+ export interface PackageLockParser {
18
+ parse(content: string): PackageLockParseResult;
19
+ }
20
+ //# sourceMappingURL=package-lock-parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package-lock-parser.d.ts","sourceRoot":"","sources":["../../../src/application/ports/package-lock-parser.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAClD,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;CAC9B;AAED,MAAM,MAAM,sBAAsB,GAC9B,QAAQ,CAAC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,aAAa,CAAC,CAAA;CAAE,CAAC,GACpE,QAAQ,CAAC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,SAAS,GAAG,aAAa,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAE7E,2CAA2C;AAC3C,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,sBAAsB,CAAC;CAChD"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=package-lock-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package-lock-parser.js","sourceRoot":"","sources":["../../../src/application/ports/package-lock-parser.ts"],"names":[],"mappings":""}
@@ -0,0 +1,12 @@
1
+ import type { Finding } from "../../domain/finding.js";
2
+ import type { AnalysisContext, AnalysisRule } from "../ports/analysis-rule.js";
3
+ import type { FileSnapshotSource } from "../ports/file-snapshot-source.js";
4
+ import type { PackageLockParser } from "../ports/package-lock-parser.js";
5
+ /** 선언 버전이 아닌, npm이 실제로 고정한 패키지 버전과 설치 위치의 변화를 분석한다. */
6
+ export declare class NpmLockfileRule implements AnalysisRule {
7
+ private readonly snapshots;
8
+ private readonly parser;
9
+ constructor(snapshots: FileSnapshotSource, parser: PackageLockParser);
10
+ analyze(context: AnalysisContext): Promise<readonly Finding[]>;
11
+ }
12
+ //# sourceMappingURL=npm-lockfile-rule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"npm-lockfile-rule.d.ts","sourceRoot":"","sources":["../../../src/application/rules/npm-lockfile-rule.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC/E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AAC3E,OAAO,KAAK,EAAiB,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAIxF,uDAAuD;AACvD,qBAAa,eAAgB,YAAW,YAAY;IAEhD,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,MAAM;gBADN,SAAS,EAAE,kBAAkB,EAC7B,MAAM,EAAE,iBAAiB;IAG/B,OAAO,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,SAAS,OAAO,EAAE,CAAC;CAiC5E"}
@@ -0,0 +1,109 @@
1
+ const lockfilePath = "package-lock.json";
2
+ /** 선언 버전이 아닌, npm이 실제로 고정한 패키지 버전과 설치 위치의 변화를 분석한다. */
3
+ export class NpmLockfileRule {
4
+ snapshots;
5
+ parser;
6
+ constructor(snapshots, parser) {
7
+ this.snapshots = snapshots;
8
+ this.parser = parser;
9
+ }
10
+ async analyze(context) {
11
+ if (!context.changes.files.some((change) => change.path === lockfilePath || change.previousPath === lockfilePath)) {
12
+ return [];
13
+ }
14
+ const snapshot = await this.snapshots.read(context.target, lockfilePath);
15
+ const before = snapshot.before === undefined ? undefined : this.parser.parse(snapshot.before);
16
+ const after = snapshot.after === undefined ? undefined : this.parser.parse(snapshot.after);
17
+ const errors = [
18
+ ...(before !== undefined && !before.ok ? [parseFinding("base", before)] : []),
19
+ ...(after !== undefined && !after.ok ? [parseFinding("current", after)] : []),
20
+ ];
21
+ if (errors.length > 0) {
22
+ return errors;
23
+ }
24
+ if (before === undefined && after === undefined) {
25
+ return [];
26
+ }
27
+ if (before === undefined && after?.ok) {
28
+ return [lockfilePresenceFinding("added", after.packages.size)];
29
+ }
30
+ if (after === undefined && before?.ok) {
31
+ return [lockfilePresenceFinding("removed", before.packages.size)];
32
+ }
33
+ if (before?.ok && after?.ok) {
34
+ return comparePackages(before.packages, after.packages);
35
+ }
36
+ return [];
37
+ }
38
+ }
39
+ function comparePackages(before, after) {
40
+ const paths = [...new Set([...before.keys(), ...after.keys()])].sort();
41
+ const findings = [];
42
+ for (const path of paths) {
43
+ const previous = before.get(path);
44
+ const current = after.get(path);
45
+ if (previous === undefined && current !== undefined) {
46
+ findings.push({
47
+ ruleId: "dependency/locked-package-added",
48
+ severity: "low",
49
+ title: "Resolved package added",
50
+ description: `${current.name}@${current.version} was added at ${path}.`,
51
+ file: lockfilePath,
52
+ evidence: packageEvidence(current),
53
+ });
54
+ }
55
+ else if (previous !== undefined && current === undefined) {
56
+ findings.push({
57
+ ruleId: "dependency/locked-package-removed",
58
+ severity: "low",
59
+ title: "Resolved package removed",
60
+ description: `${previous.name}@${previous.version} was removed from ${path}.`,
61
+ file: lockfilePath,
62
+ evidence: packageEvidence(previous),
63
+ });
64
+ }
65
+ else if (previous !== undefined &&
66
+ current !== undefined &&
67
+ previous.version !== current.version) {
68
+ findings.push({
69
+ ruleId: "dependency/locked-version-changed",
70
+ severity: "low",
71
+ title: "Resolved package version changed",
72
+ description: `${current.name} at ${path} changed from ${previous.version} to ${current.version}.`,
73
+ file: lockfilePath,
74
+ evidence: { ...packageEvidence(current), from: previous.version, to: current.version },
75
+ });
76
+ }
77
+ }
78
+ return findings;
79
+ }
80
+ function packageEvidence(item) {
81
+ return {
82
+ package: item.name,
83
+ version: item.version,
84
+ installPath: item.path,
85
+ rootDirect: item.rootDirect,
86
+ };
87
+ }
88
+ function parseFinding(side, result) {
89
+ const unsupported = result.kind === "unsupported";
90
+ return {
91
+ ruleId: unsupported ? "dependency/unsupported-lockfile" : "dependency/invalid-lockfile",
92
+ severity: unsupported ? "low" : "high",
93
+ title: unsupported ? "Unsupported npm lockfile" : "Invalid npm lockfile",
94
+ description: `Could not analyze the ${side} package-lock.json: ${result.reason}`,
95
+ file: lockfilePath,
96
+ evidence: { side, reason: result.reason },
97
+ };
98
+ }
99
+ function lockfilePresenceFinding(kind, packageCount) {
100
+ return {
101
+ ruleId: `dependency/lockfile-${kind}`,
102
+ severity: "low",
103
+ title: kind === "added" ? "npm lockfile added" : "npm lockfile removed",
104
+ description: `package-lock.json was ${kind} with ${packageCount} resolved packages.`,
105
+ file: lockfilePath,
106
+ evidence: { packageCount },
107
+ };
108
+ }
109
+ //# sourceMappingURL=npm-lockfile-rule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"npm-lockfile-rule.js","sourceRoot":"","sources":["../../../src/application/rules/npm-lockfile-rule.ts"],"names":[],"mappings":"AAKA,MAAM,YAAY,GAAG,mBAAmB,CAAC;AAEzC,uDAAuD;AACvD,MAAM,OAAO,eAAe;IAEP;IACA;IAFnB,YACmB,SAA6B,EAC7B,MAAyB;QADzB,cAAS,GAAT,SAAS,CAAoB;QAC7B,WAAM,GAAN,MAAM,CAAmB;IACzC,CAAC;IAEG,KAAK,CAAC,OAAO,CAAC,OAAwB;QAC3C,IACE,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CACzB,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,YAAY,IAAI,MAAM,CAAC,YAAY,KAAK,YAAY,CACjF,EACD,CAAC;YACD,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;QACzE,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC9F,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC3F,MAAM,MAAM,GAAG;YACb,GAAG,CAAC,MAAM,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7E,GAAG,CAAC,KAAK,KAAK,SAAS,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;SAC9E,CAAC;QACF,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,IAAI,MAAM,KAAK,SAAS,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YAChD,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,IAAI,MAAM,KAAK,SAAS,IAAI,KAAK,EAAE,EAAE,EAAE,CAAC;YACtC,OAAO,CAAC,uBAAuB,CAAC,OAAO,EAAE,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;QACjE,CAAC;QACD,IAAI,KAAK,KAAK,SAAS,IAAI,MAAM,EAAE,EAAE,EAAE,CAAC;YACtC,OAAO,CAAC,uBAAuB,CAAC,SAAS,EAAE,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;QACpE,CAAC;QACD,IAAI,MAAM,EAAE,EAAE,IAAI,KAAK,EAAE,EAAE,EAAE,CAAC;YAC5B,OAAO,eAAe,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC1D,CAAC;QACD,OAAO,EAAE,CAAC;IACZ,CAAC;CACF;AAED,SAAS,eAAe,CACtB,MAA0C,EAC1C,KAAyC;IAEzC,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,EAAE,EAAE,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACvE,MAAM,QAAQ,GAAc,EAAE,CAAC;IAC/B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAClC,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAChC,IAAI,QAAQ,KAAK,SAAS,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YACpD,QAAQ,CAAC,IAAI,CAAC;gBACZ,MAAM,EAAE,iCAAiC;gBACzC,QAAQ,EAAE,KAAK;gBACf,KAAK,EAAE,wBAAwB;gBAC/B,WAAW,EAAE,GAAG,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,OAAO,iBAAiB,IAAI,GAAG;gBACvE,IAAI,EAAE,YAAY;gBAClB,QAAQ,EAAE,eAAe,CAAC,OAAO,CAAC;aACnC,CAAC,CAAC;QACL,CAAC;aAAM,IAAI,QAAQ,KAAK,SAAS,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC3D,QAAQ,CAAC,IAAI,CAAC;gBACZ,MAAM,EAAE,mCAAmC;gBAC3C,QAAQ,EAAE,KAAK;gBACf,KAAK,EAAE,0BAA0B;gBACjC,WAAW,EAAE,GAAG,QAAQ,CAAC,IAAI,IAAI,QAAQ,CAAC,OAAO,qBAAqB,IAAI,GAAG;gBAC7E,IAAI,EAAE,YAAY;gBAClB,QAAQ,EAAE,eAAe,CAAC,QAAQ,CAAC;aACpC,CAAC,CAAC;QACL,CAAC;aAAM,IACL,QAAQ,KAAK,SAAS;YACtB,OAAO,KAAK,SAAS;YACrB,QAAQ,CAAC,OAAO,KAAK,OAAO,CAAC,OAAO,EACpC,CAAC;YACD,QAAQ,CAAC,IAAI,CAAC;gBACZ,MAAM,EAAE,mCAAmC;gBAC3C,QAAQ,EAAE,KAAK;gBACf,KAAK,EAAE,kCAAkC;gBACzC,WAAW,EAAE,GAAG,OAAO,CAAC,IAAI,OAAO,IAAI,iBAAiB,QAAQ,CAAC,OAAO,OAAO,OAAO,CAAC,OAAO,GAAG;gBACjG,IAAI,EAAE,YAAY;gBAClB,QAAQ,EAAE,EAAE,GAAG,eAAe,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,OAAO,EAAE,EAAE,EAAE,OAAO,CAAC,OAAO,EAAE;aACvF,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,eAAe,CAAC,IAAmB;IAC1C,OAAO;QACL,OAAO,EAAE,IAAI,CAAC,IAAI;QAClB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,WAAW,EAAE,IAAI,CAAC,IAAI;QACtB,UAAU,EAAE,IAAI,CAAC,UAAU;KAC5B,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CACnB,IAAwB,EACxB,MAAsE;IAEtE,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,KAAK,aAAa,CAAC;IAClD,OAAO;QACL,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,iCAAiC,CAAC,CAAC,CAAC,6BAA6B;QACvF,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM;QACtC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,sBAAsB;QACxE,WAAW,EAAE,yBAAyB,IAAI,uBAAuB,MAAM,CAAC,MAAM,EAAE;QAChF,IAAI,EAAE,YAAY;QAClB,QAAQ,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE;KAC1C,CAAC;AACJ,CAAC;AAED,SAAS,uBAAuB,CAAC,IAAyB,EAAE,YAAoB;IAC9E,OAAO;QACL,MAAM,EAAE,uBAAuB,IAAI,EAAE;QACrC,QAAQ,EAAE,KAAK;QACf,KAAK,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,sBAAsB;QACvE,WAAW,EAAE,yBAAyB,IAAI,SAAS,YAAY,qBAAqB;QACpF,IAAI,EAAE,YAAY;QAClB,QAAQ,EAAE,EAAE,YAAY,EAAE;KAC3B,CAAC;AACJ,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { Finding } from "../../domain/finding.js";
2
+ import type { AnalysisContext, AnalysisRule } from "../ports/analysis-rule.js";
3
+ import type { FileSnapshotSource } from "../ports/file-snapshot-source.js";
4
+ /** npm workspaces에 속한 변경 manifest를 찾아 기존 직접 dependency 규칙으로 분석한다. */
5
+ export declare class NpmWorkspaceDependencyRule implements AnalysisRule {
6
+ private readonly snapshots;
7
+ constructor(snapshots: FileSnapshotSource);
8
+ analyze(context: AnalysisContext): Promise<readonly Finding[]>;
9
+ }
10
+ //# sourceMappingURL=npm-workspace-dependency-rule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"npm-workspace-dependency-rule.d.ts","sourceRoot":"","sources":["../../../src/application/rules/npm-workspace-dependency-rule.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC/E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AAW3E,qEAAqE;AACrE,qBAAa,0BAA2B,YAAW,YAAY;IAC1C,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAAT,SAAS,EAAE,kBAAkB;IAEpD,OAAO,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,SAAS,OAAO,EAAE,CAAC;CAwF5E"}
@@ -0,0 +1,155 @@
1
+ import { matchesPathPattern } from "../services/path-pattern.js";
2
+ import { PackageDependencyRule } from "./package-dependency-rule.js";
3
+ const rootManifestPath = "package.json";
4
+ const manifestSuffix = "/package.json";
5
+ /** npm workspaces에 속한 변경 manifest를 찾아 기존 직접 dependency 규칙으로 분석한다. */
6
+ export class NpmWorkspaceDependencyRule {
7
+ snapshots;
8
+ constructor(snapshots) {
9
+ this.snapshots = snapshots;
10
+ }
11
+ async analyze(context) {
12
+ const manifestChanges = context.changes.files.filter(isNestedManifestChange);
13
+ const rootChanged = context.changes.files.some((change) => change.path === rootManifestPath || change.previousPath === rootManifestPath);
14
+ if (manifestChanges.length === 0 && !rootChanged) {
15
+ return [];
16
+ }
17
+ const snapshot = await this.snapshots.read(context.target, rootManifestPath);
18
+ const before = parseWorkspaceConfig(snapshot.before);
19
+ const after = parseWorkspaceConfig(snapshot.after);
20
+ const errors = [
21
+ ...(!before.ok ? [configFinding("base", before)] : []),
22
+ ...(!after.ok ? [configFinding("current", after)] : []),
23
+ ];
24
+ if (errors.length > 0) {
25
+ return errors;
26
+ }
27
+ if (!before.ok || !after.ok) {
28
+ return [];
29
+ }
30
+ const findings = [];
31
+ if (rootChanged && JSON.stringify(before.patterns) !== JSON.stringify(after.patterns)) {
32
+ findings.push({
33
+ ruleId: "dependency/workspace-config-changed",
34
+ severity: "low",
35
+ title: "npm workspace configuration changed",
36
+ description: "The root package.json workspace patterns changed.",
37
+ file: rootManifestPath,
38
+ evidence: {
39
+ from: JSON.stringify(before.patterns),
40
+ to: JSON.stringify(after.patterns),
41
+ },
42
+ });
43
+ }
44
+ const results = await Promise.all(manifestChanges.map(async (change) => {
45
+ const previousPath = change.kind === "renamed" ? (change.previousPath ?? change.path) : change.path;
46
+ const currentPath = change.path;
47
+ const wasWorkspace = change.kind !== "added" &&
48
+ change.kind !== "copied" &&
49
+ isConfiguredWorkspace(previousPath, before.patterns);
50
+ const isWorkspace = change.kind !== "deleted" && isConfiguredWorkspace(currentPath, after.patterns);
51
+ if (!wasWorkspace && !isWorkspace) {
52
+ return [];
53
+ }
54
+ const manifestPath = isNestedManifestPath(currentPath) ? currentPath : previousPath;
55
+ const workspacePath = manifestPath.slice(0, -manifestSuffix.length);
56
+ const membershipFinding = change.kind === "renamed" && wasWorkspace !== isWorkspace
57
+ ? [
58
+ {
59
+ ruleId: "dependency/workspace-membership-changed",
60
+ severity: "low",
61
+ title: "npm workspace membership changed",
62
+ description: `${previousPath} moved to ${currentPath}, changing workspace membership.`,
63
+ file: currentPath,
64
+ evidence: {
65
+ previousPath,
66
+ currentPath,
67
+ fromWorkspace: wasWorkspace,
68
+ toWorkspace: isWorkspace,
69
+ },
70
+ },
71
+ ]
72
+ : [];
73
+ const dependencyFindings = await new PackageDependencyRule(this.snapshots, manifestPath).analyze(context);
74
+ return [
75
+ ...membershipFinding,
76
+ ...dependencyFindings.map((finding) => ({
77
+ ...finding,
78
+ evidence: { ...finding.evidence, workspace: workspacePath },
79
+ })),
80
+ ];
81
+ }));
82
+ return [...findings, ...results.flat()];
83
+ }
84
+ }
85
+ function isNestedManifestChange(change) {
86
+ return isNestedManifestPath(change.path) || isNestedManifestPath(change.previousPath);
87
+ }
88
+ function isNestedManifestPath(path) {
89
+ return path?.endsWith(manifestSuffix) === true;
90
+ }
91
+ function isConfiguredWorkspace(path, patterns) {
92
+ if (!isNestedManifestPath(path)) {
93
+ return false;
94
+ }
95
+ const directory = path.slice(0, -manifestSuffix.length);
96
+ return patterns.some((pattern) => matchesPathPattern(directory, pattern));
97
+ }
98
+ function parseWorkspaceConfig(content) {
99
+ if (content === undefined) {
100
+ return { ok: true, patterns: [] };
101
+ }
102
+ let manifest;
103
+ try {
104
+ manifest = JSON.parse(content);
105
+ }
106
+ catch {
107
+ return { ok: false, kind: "invalid", reason: "The root package.json is not valid JSON." };
108
+ }
109
+ if (!isRecord(manifest)) {
110
+ return { ok: false, kind: "invalid", reason: "The root package.json must be an object." };
111
+ }
112
+ if (manifest.workspaces === undefined) {
113
+ return { ok: true, patterns: [] };
114
+ }
115
+ if (!Array.isArray(manifest.workspaces)) {
116
+ return { ok: false, kind: "invalid", reason: "workspaces must be an array of paths." };
117
+ }
118
+ const patterns = [];
119
+ for (const rawPattern of manifest.workspaces) {
120
+ if (typeof rawPattern !== "string" || rawPattern.trim().length === 0) {
121
+ return { ok: false, kind: "invalid", reason: "Each workspace path must be a string." };
122
+ }
123
+ const pattern = rawPattern.replace(/^(\.\/)+/, "").replace(/\/+$/, "");
124
+ if (pattern.length === 0 || pattern.startsWith("/") || pattern.split("/").includes("..")) {
125
+ return { ok: false, kind: "invalid", reason: `Invalid workspace path: ${rawPattern}.` };
126
+ }
127
+ if (["!", "{", "}", "[", "]", "\\"].some((character) => pattern.includes(character))) {
128
+ return {
129
+ ok: false,
130
+ kind: "unsupported",
131
+ reason: `Unsupported workspace pattern: ${rawPattern}. Only *, **, and ? globs are supported.`,
132
+ };
133
+ }
134
+ patterns.push(pattern);
135
+ }
136
+ return { ok: true, patterns };
137
+ }
138
+ function configFinding(side, result) {
139
+ return {
140
+ ruleId: result.kind === "invalid"
141
+ ? "dependency/invalid-workspace-config"
142
+ : "dependency/unsupported-workspace-pattern",
143
+ severity: result.kind === "invalid" ? "high" : "low",
144
+ title: result.kind === "invalid"
145
+ ? "Invalid npm workspace configuration"
146
+ : "Unsupported npm workspace pattern",
147
+ description: `Could not analyze the ${side} npm workspaces: ${result.reason}`,
148
+ file: rootManifestPath,
149
+ evidence: { side, reason: result.reason },
150
+ };
151
+ }
152
+ function isRecord(value) {
153
+ return typeof value === "object" && value !== null && !Array.isArray(value);
154
+ }
155
+ //# sourceMappingURL=npm-workspace-dependency-rule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"npm-workspace-dependency-rule.js","sourceRoot":"","sources":["../../../src/application/rules/npm-workspace-dependency-rule.ts"],"names":[],"mappings":"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"}
@@ -2,12 +2,13 @@ import type { Finding } from "../../domain/finding.js";
2
2
  import type { AnalysisContext, AnalysisRule } from "../ports/analysis-rule.js";
3
3
  import type { FileSnapshotSource } from "../ports/file-snapshot-source.js";
4
4
  /**
5
- * 루트 package.json의 직접 dependency 변경만 판단한다.
6
- * lockfile의 전이 dependency와 workspace package 지원은 별도 규칙으로 확장한다.
5
+ * 한 package.json의 직접 dependency 선언 변경을 판단한다.
6
+ * 루트와 workspace 규칙이 같은 판단 기준을 사용하도록 경로를 주입받는다.
7
7
  */
8
8
  export declare class PackageDependencyRule implements AnalysisRule {
9
9
  private readonly snapshots;
10
- constructor(snapshots: FileSnapshotSource);
10
+ private readonly manifestPath;
11
+ constructor(snapshots: FileSnapshotSource, manifestPath?: string);
11
12
  analyze(context: AnalysisContext): Promise<readonly Finding[]>;
12
13
  }
13
14
  //# sourceMappingURL=package-dependency-rule.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"package-dependency-rule.d.ts","sourceRoot":"","sources":["../../../src/application/rules/package-dependency-rule.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAY,MAAM,yBAAyB,CAAC;AACjE,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC/E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AAgB3E;;;GAGG;AACH,qBAAa,qBAAsB,YAAW,YAAY;IACrC,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAAT,SAAS,EAAE,kBAAkB;IAEpD,OAAO,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,SAAS,OAAO,EAAE,CAAC;CAoB5E"}
1
+ {"version":3,"file":"package-dependency-rule.d.ts","sourceRoot":"","sources":["../../../src/application/rules/package-dependency-rule.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAY,MAAM,yBAAyB,CAAC;AACjE,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC/E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AAgB3E;;;GAGG;AACH,qBAAa,qBAAsB,YAAW,YAAY;IAEtD,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,YAAY;gBADZ,SAAS,EAAE,kBAAkB,EAC7B,YAAY,SAAmB;IAGrC,OAAO,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,SAAS,OAAO,EAAE,CAAC;CA6B5E"}
@@ -1,21 +1,26 @@
1
- const manifestPath = "package.json";
1
+ const rootManifestPath = "package.json";
2
2
  const dependencySections = ["dependencies", "devDependencies"];
3
3
  /**
4
- * 루트 package.json의 직접 dependency 변경만 판단한다.
5
- * lockfile의 전이 dependency와 workspace package 지원은 별도 규칙으로 확장한다.
4
+ * 한 package.json의 직접 dependency 선언 변경을 판단한다.
5
+ * 루트와 workspace 규칙이 같은 판단 기준을 사용하도록 경로를 주입받는다.
6
6
  */
7
7
  export class PackageDependencyRule {
8
8
  snapshots;
9
- constructor(snapshots) {
9
+ manifestPath;
10
+ constructor(snapshots, manifestPath = rootManifestPath) {
10
11
  this.snapshots = snapshots;
12
+ this.manifestPath = manifestPath;
11
13
  }
12
14
  async analyze(context) {
13
- if (!context.changes.files.some(isManifestChange)) {
15
+ const change = context.changes.files.find((item) => item.path === this.manifestPath || item.previousPath === this.manifestPath);
16
+ if (change === undefined) {
14
17
  return [];
15
18
  }
16
- const snapshot = await this.snapshots.read(context.target, manifestPath);
17
- const before = parseManifest(snapshot.before, "base");
18
- const after = parseManifest(snapshot.after, "current");
19
+ const snapshot = await this.snapshots.read(context.target, this.manifestPath, change.kind === "renamed" && isPackageManifestPath(change.previousPath)
20
+ ? change.previousPath
21
+ : undefined);
22
+ const before = parseManifest(snapshot.before, "base", this.manifestPath);
23
+ const after = parseManifest(snapshot.after, "current", this.manifestPath);
19
24
  if (!before.ok && !after.ok) {
20
25
  return [before.finding, after.finding];
21
26
  }
@@ -25,13 +30,13 @@ export class PackageDependencyRule {
25
30
  if (!after.ok) {
26
31
  return [after.finding];
27
32
  }
28
- return compareDependencies(before.dependencies, after.dependencies);
33
+ return compareDependencies(before.dependencies, after.dependencies, this.manifestPath);
29
34
  }
30
35
  }
31
- function isManifestChange(change) {
32
- return change.path === manifestPath || change.previousPath === manifestPath;
36
+ function isPackageManifestPath(path) {
37
+ return path === rootManifestPath || path?.endsWith("/package.json") === true;
33
38
  }
34
- function parseManifest(content, side) {
39
+ function parseManifest(content, side, manifestPath) {
35
40
  if (content === undefined) {
36
41
  return { ok: true, dependencies: new Map() };
37
42
  }
@@ -40,10 +45,10 @@ function parseManifest(content, side) {
40
45
  value = JSON.parse(content);
41
46
  }
42
47
  catch {
43
- return invalidManifest(side, "The file is not valid JSON.");
48
+ return invalidManifest(side, "The file is not valid JSON.", manifestPath);
44
49
  }
45
50
  if (!isRecord(value)) {
46
- return invalidManifest(side, "The root value must be a JSON object.");
51
+ return invalidManifest(side, "The root value must be a JSON object.", manifestPath);
47
52
  }
48
53
  const dependencies = new Map();
49
54
  for (const section of dependencySections) {
@@ -52,48 +57,48 @@ function parseManifest(content, side) {
52
57
  continue;
53
58
  }
54
59
  if (!isRecord(entries)) {
55
- return invalidManifest(side, `${section} must be a JSON object.`);
60
+ return invalidManifest(side, `${section} must be a JSON object.`, manifestPath);
56
61
  }
57
62
  for (const [name, version] of Object.entries(entries)) {
58
63
  if (typeof version !== "string") {
59
- return invalidManifest(side, `${section}.${name} must have a string version.`);
64
+ return invalidManifest(side, `${section}.${name} must have a string version.`, manifestPath);
60
65
  }
61
66
  if (dependencies.has(name)) {
62
- return invalidManifest(side, `${name} is declared in more than one dependency section.`);
67
+ return invalidManifest(side, `${name} is declared in more than one dependency section.`, manifestPath);
63
68
  }
64
69
  dependencies.set(name, { section, version });
65
70
  }
66
71
  }
67
72
  return { ok: true, dependencies };
68
73
  }
69
- function compareDependencies(before, after) {
74
+ function compareDependencies(before, after, manifestPath) {
70
75
  const names = [...new Set([...before.keys(), ...after.keys()])].sort((left, right) => left.localeCompare(right));
71
76
  const findings = [];
72
77
  for (const name of names) {
73
78
  const previous = before.get(name);
74
79
  const current = after.get(name);
75
80
  if (previous === undefined && current !== undefined) {
76
- findings.push(addedDependency(name, current));
81
+ findings.push(addedDependency(name, current, manifestPath));
77
82
  continue;
78
83
  }
79
84
  if (previous !== undefined && current === undefined) {
80
- findings.push(removedDependency(name, previous));
85
+ findings.push(removedDependency(name, previous, manifestPath));
81
86
  continue;
82
87
  }
83
88
  if (previous === undefined || current === undefined) {
84
89
  continue;
85
90
  }
86
91
  if (previous.section !== current.section) {
87
- findings.push(movedDependency(name, previous, current));
92
+ findings.push(movedDependency(name, previous, current, manifestPath));
88
93
  continue;
89
94
  }
90
95
  if (previous.version !== current.version) {
91
- findings.push(changedDependency(name, previous, current));
96
+ findings.push(changedDependency(name, previous, current, manifestPath));
92
97
  }
93
98
  }
94
99
  return findings;
95
100
  }
96
- function addedDependency(name, declaration) {
101
+ function addedDependency(name, declaration, manifestPath) {
97
102
  const production = declaration.section === "dependencies";
98
103
  return {
99
104
  ruleId: production ? "dependency/new-production" : "dependency/new-development",
@@ -108,7 +113,7 @@ function addedDependency(name, declaration) {
108
113
  },
109
114
  };
110
115
  }
111
- function removedDependency(name, declaration) {
116
+ function removedDependency(name, declaration, manifestPath) {
112
117
  return {
113
118
  ruleId: "dependency/removed",
114
119
  severity: "low",
@@ -122,7 +127,7 @@ function removedDependency(name, declaration) {
122
127
  },
123
128
  };
124
129
  }
125
- function movedDependency(name, previous, current) {
130
+ function movedDependency(name, previous, current, manifestPath) {
126
131
  return {
127
132
  ruleId: "dependency/section-changed",
128
133
  severity: current.section === "dependencies" ? "medium" : "low",
@@ -137,7 +142,7 @@ function movedDependency(name, previous, current) {
137
142
  },
138
143
  };
139
144
  }
140
- function changedDependency(name, previous, current) {
145
+ function changedDependency(name, previous, current, manifestPath) {
141
146
  return {
142
147
  ruleId: "dependency/version-changed",
143
148
  severity: severityFor(current.section),
@@ -152,14 +157,14 @@ function changedDependency(name, previous, current) {
152
157
  },
153
158
  };
154
159
  }
155
- function invalidManifest(side, reason) {
160
+ function invalidManifest(side, reason, manifestPath) {
156
161
  return {
157
162
  ok: false,
158
163
  finding: {
159
164
  ruleId: "dependency/invalid-manifest",
160
165
  severity: "high",
161
166
  title: "Invalid package manifest",
162
- description: `Could not analyze the ${side} package.json: ${reason}`,
167
+ description: `Could not analyze the ${side} ${manifestPath}: ${reason}`,
163
168
  file: manifestPath,
164
169
  evidence: { side, reason },
165
170
  },
@@ -1 +1 @@
1
- {"version":3,"file":"package-dependency-rule.js","sourceRoot":"","sources":["../../../src/application/rules/package-dependency-rule.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"package-dependency-rule.js","sourceRoot":"","sources":["../../../src/application/rules/package-dependency-rule.ts"],"names":[],"mappings":"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"}
@@ -1,13 +1,15 @@
1
1
  import { type ImpactAnalysis } from "../../domain/impact.js";
2
2
  import type { AnalysisContext } from "../ports/analysis-rule.js";
3
3
  import type { ChangeImpactAnalyzer } from "../ports/change-impact-analyzer.js";
4
+ import type { ModuleAliasResolver } from "../ports/module-alias-resolver.js";
4
5
  import type { ModuleReferenceExtractor } from "../ports/module-reference-extractor.js";
5
6
  import type { ProjectFileSource } from "../ports/project-file-source.js";
6
7
  /** 현재 module graph를 역방향으로 탐색해 변경 파일의 직접·간접 의존자를 찾는다. */
7
8
  export declare class AnalyzeImportImpact implements ChangeImpactAnalyzer {
8
9
  private readonly files;
9
10
  private readonly extractors;
10
- constructor(files: ProjectFileSource, extractors: readonly ModuleReferenceExtractor[]);
11
+ private readonly aliases;
12
+ constructor(files: ProjectFileSource, extractors: readonly ModuleReferenceExtractor[], aliases: ModuleAliasResolver);
11
13
  analyze(context: AnalysisContext): Promise<ImpactAnalysis>;
12
14
  private extractorFor;
13
15
  }
@@ -1 +1 @@
1
- {"version":3,"file":"analyze-import-impact.d.ts","sourceRoot":"","sources":["../../../src/application/services/analyze-import-impact.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,cAAc,EAKpB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAC/E,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,wCAAwC,CAAC;AACvF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAKzE,wDAAwD;AACxD,qBAAa,mBAAoB,YAAW,oBAAoB;IAE5D,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,UAAU;gBADV,KAAK,EAAE,iBAAiB,EACxB,UAAU,EAAE,SAAS,wBAAwB,EAAE;IAGrD,OAAO,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;IAyDvE,OAAO,CAAC,YAAY;CAGrB"}
1
+ {"version":3,"file":"analyze-import-impact.d.ts","sourceRoot":"","sources":["../../../src/application/services/analyze-import-impact.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,cAAc,EAKpB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAC/E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAC7E,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,wCAAwC,CAAC;AACvF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAKzE,wDAAwD;AACxD,qBAAa,mBAAoB,YAAW,oBAAoB;IAE5D,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAFP,KAAK,EAAE,iBAAiB,EACxB,UAAU,EAAE,SAAS,wBAAwB,EAAE,EAC/C,OAAO,EAAE,mBAAmB;IAGlC,OAAO,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;IA4DvE,OAAO,CAAC,YAAY;CAGrB"}