intentpatch 0.1.1 → 0.3.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 (116) hide show
  1. package/README.ko.md +74 -22
  2. package/README.md +62 -17
  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/module-reference-extractor.d.ts +1 -0
  8. package/dist/application/ports/module-reference-extractor.d.ts.map +1 -1
  9. package/dist/application/ports/package-lock-parser.d.ts +20 -0
  10. package/dist/application/ports/package-lock-parser.d.ts.map +1 -0
  11. package/dist/application/ports/package-lock-parser.js +2 -0
  12. package/dist/application/ports/package-lock-parser.js.map +1 -0
  13. package/dist/application/ports/parse-failure.d.ts +7 -0
  14. package/dist/application/ports/parse-failure.d.ts.map +1 -0
  15. package/dist/application/ports/parse-failure.js +5 -0
  16. package/dist/application/ports/parse-failure.js.map +1 -0
  17. package/dist/application/ports/pnpm-lock-parser.d.ts +20 -0
  18. package/dist/application/ports/pnpm-lock-parser.d.ts.map +1 -0
  19. package/dist/application/ports/pnpm-lock-parser.js +2 -0
  20. package/dist/application/ports/pnpm-lock-parser.js.map +1 -0
  21. package/dist/application/ports/pnpm-workspace-parser.d.ts +14 -0
  22. package/dist/application/ports/pnpm-workspace-parser.d.ts.map +1 -0
  23. package/dist/application/ports/pnpm-workspace-parser.js +2 -0
  24. package/dist/application/ports/pnpm-workspace-parser.js.map +1 -0
  25. package/dist/application/rules/added-dependency-usage-rule.d.ts +16 -0
  26. package/dist/application/rules/added-dependency-usage-rule.d.ts.map +1 -0
  27. package/dist/application/rules/added-dependency-usage-rule.js +98 -0
  28. package/dist/application/rules/added-dependency-usage-rule.js.map +1 -0
  29. package/dist/application/rules/npm-lockfile-rule.d.ts +12 -0
  30. package/dist/application/rules/npm-lockfile-rule.d.ts.map +1 -0
  31. package/dist/application/rules/npm-lockfile-rule.js +109 -0
  32. package/dist/application/rules/npm-lockfile-rule.js.map +1 -0
  33. package/dist/application/rules/npm-workspace-dependency-rule.d.ts +10 -0
  34. package/dist/application/rules/npm-workspace-dependency-rule.d.ts.map +1 -0
  35. package/dist/application/rules/npm-workspace-dependency-rule.js +107 -0
  36. package/dist/application/rules/npm-workspace-dependency-rule.js.map +1 -0
  37. package/dist/application/rules/package-dependency-rule.d.ts +4 -3
  38. package/dist/application/rules/package-dependency-rule.d.ts.map +1 -1
  39. package/dist/application/rules/package-dependency-rule.js +34 -31
  40. package/dist/application/rules/package-dependency-rule.js.map +1 -1
  41. package/dist/application/rules/pnpm-lockfile-rule.d.ts +12 -0
  42. package/dist/application/rules/pnpm-lockfile-rule.d.ts.map +1 -0
  43. package/dist/application/rules/pnpm-lockfile-rule.js +119 -0
  44. package/dist/application/rules/pnpm-lockfile-rule.js.map +1 -0
  45. package/dist/application/rules/pnpm-workspace-dependency-rule.d.ts +12 -0
  46. package/dist/application/rules/pnpm-workspace-dependency-rule.d.ts.map +1 -0
  47. package/dist/application/rules/pnpm-workspace-dependency-rule.js +59 -0
  48. package/dist/application/rules/pnpm-workspace-dependency-rule.js.map +1 -0
  49. package/dist/application/services/analyze-import-impact.d.ts +3 -1
  50. package/dist/application/services/analyze-import-impact.d.ts.map +1 -1
  51. package/dist/application/services/analyze-import-impact.js +12 -7
  52. package/dist/application/services/analyze-import-impact.js.map +1 -1
  53. package/dist/application/services/workspace-manifest-analysis.d.ts +12 -0
  54. package/dist/application/services/workspace-manifest-analysis.d.ts.map +1 -0
  55. package/dist/application/services/workspace-manifest-analysis.js +60 -0
  56. package/dist/application/services/workspace-manifest-analysis.js.map +1 -0
  57. package/dist/domain/value-guards.d.ts +3 -0
  58. package/dist/domain/value-guards.d.ts.map +1 -0
  59. package/dist/domain/value-guards.js +5 -0
  60. package/dist/domain/value-guards.js.map +1 -0
  61. package/dist/infrastructure/config/json-change-contract-loader.d.ts.map +1 -1
  62. package/dist/infrastructure/config/json-change-contract-loader.js +1 -3
  63. package/dist/infrastructure/config/json-change-contract-loader.js.map +1 -1
  64. package/dist/infrastructure/config/text-intent-loader.d.ts +5 -0
  65. package/dist/infrastructure/config/text-intent-loader.d.ts.map +1 -0
  66. package/dist/infrastructure/config/text-intent-loader.js +30 -0
  67. package/dist/infrastructure/config/text-intent-loader.js.map +1 -0
  68. package/dist/infrastructure/git/git-file-snapshot-source.d.ts.map +1 -1
  69. package/dist/infrastructure/git/git-file-snapshot-source.js +6 -2
  70. package/dist/infrastructure/git/git-file-snapshot-source.js.map +1 -1
  71. package/dist/infrastructure/npm/npm-package-lock-parser.d.ts +6 -0
  72. package/dist/infrastructure/npm/npm-package-lock-parser.d.ts.map +1 -0
  73. package/dist/infrastructure/npm/npm-package-lock-parser.js +89 -0
  74. package/dist/infrastructure/npm/npm-package-lock-parser.js.map +1 -0
  75. package/dist/infrastructure/pnpm/pnpm-lock-parser.d.ts +6 -0
  76. package/dist/infrastructure/pnpm/pnpm-lock-parser.d.ts.map +1 -0
  77. package/dist/infrastructure/pnpm/pnpm-lock-parser.js +122 -0
  78. package/dist/infrastructure/pnpm/pnpm-lock-parser.js.map +1 -0
  79. package/dist/infrastructure/pnpm/pnpm-workspace-parser.d.ts +6 -0
  80. package/dist/infrastructure/pnpm/pnpm-workspace-parser.d.ts.map +1 -0
  81. package/dist/infrastructure/pnpm/pnpm-workspace-parser.js +62 -0
  82. package/dist/infrastructure/pnpm/pnpm-workspace-parser.js.map +1 -0
  83. package/dist/infrastructure/typescript/package-module-reference-extractor.d.ts +7 -0
  84. package/dist/infrastructure/typescript/package-module-reference-extractor.d.ts.map +1 -0
  85. package/dist/infrastructure/typescript/package-module-reference-extractor.js +68 -0
  86. package/dist/infrastructure/typescript/package-module-reference-extractor.js.map +1 -0
  87. package/dist/infrastructure/typescript/typescript-config-loader.d.ts +17 -0
  88. package/dist/infrastructure/typescript/typescript-config-loader.d.ts.map +1 -0
  89. package/dist/infrastructure/typescript/typescript-config-loader.js +97 -0
  90. package/dist/infrastructure/typescript/typescript-config-loader.js.map +1 -0
  91. package/dist/infrastructure/typescript/typescript-module-alias-resolver.d.ts +10 -0
  92. package/dist/infrastructure/typescript/typescript-module-alias-resolver.d.ts.map +1 -0
  93. package/dist/infrastructure/typescript/typescript-module-alias-resolver.js +78 -0
  94. package/dist/infrastructure/typescript/typescript-module-alias-resolver.js.map +1 -0
  95. package/dist/presentation/analyze-repository.d.ts +2 -0
  96. package/dist/presentation/analyze-repository.d.ts.map +1 -1
  97. package/dist/presentation/analyze-repository.js +28 -5
  98. package/dist/presentation/analyze-repository.js.map +1 -1
  99. package/dist/presentation/cli/arguments.d.ts +1 -0
  100. package/dist/presentation/cli/arguments.d.ts.map +1 -1
  101. package/dist/presentation/cli/arguments.js +7 -0
  102. package/dist/presentation/cli/arguments.js.map +1 -1
  103. package/dist/presentation/cli/main.js +5 -0
  104. package/dist/presentation/cli/main.js.map +1 -1
  105. package/dist/presentation/github/action-inputs.d.ts +2 -0
  106. package/dist/presentation/github/action-inputs.d.ts.map +1 -1
  107. package/dist/presentation/github/action-inputs.js +10 -0
  108. package/dist/presentation/github/action-inputs.js.map +1 -1
  109. package/dist/presentation/github/pr-body-intent.d.ts +3 -0
  110. package/dist/presentation/github/pr-body-intent.d.ts.map +1 -0
  111. package/dist/presentation/github/pr-body-intent.js +15 -0
  112. package/dist/presentation/github/pr-body-intent.js.map +1 -0
  113. package/dist/presentation/github/run-action.d.ts.map +1 -1
  114. package/dist/presentation/github/run-action.js +10 -0
  115. package/dist/presentation/github/run-action.js.map +1 -1
  116. package/package.json +3 -2
@@ -0,0 +1,89 @@
1
+ import { invalidParseResult as invalid } from "../../application/ports/parse-failure.js";
2
+ import { isRecord } from "../../domain/value-guards.js";
3
+ const directDependencySections = [
4
+ "dependencies",
5
+ "devDependencies",
6
+ "optionalDependencies",
7
+ "peerDependencies",
8
+ ];
9
+ /** npm v7+의 packages 맵을 설치 위치별 사실로 변환한다. v2의 레거시 dependencies 맵은 중복 집계하지 않는다. */
10
+ export class NpmPackageLockParser {
11
+ parse(content) {
12
+ let value;
13
+ try {
14
+ value = JSON.parse(content);
15
+ }
16
+ catch {
17
+ return invalid("The file is not valid JSON.");
18
+ }
19
+ if (!isRecord(value)) {
20
+ return invalid("The root value must be a JSON object.");
21
+ }
22
+ if (typeof value.lockfileVersion !== "number" || !Number.isInteger(value.lockfileVersion)) {
23
+ return invalid("lockfileVersion must be an integer.");
24
+ }
25
+ if (value.lockfileVersion !== 2 && value.lockfileVersion !== 3) {
26
+ return {
27
+ ok: false,
28
+ kind: "unsupported",
29
+ reason: `Supported lockfile versions are 2 and 3; found ${value.lockfileVersion}.`,
30
+ };
31
+ }
32
+ if (!isRecord(value.packages)) {
33
+ return invalid("packages must be a JSON object.");
34
+ }
35
+ const root = value.packages[""];
36
+ if (root !== undefined && !isRecord(root)) {
37
+ return invalid('packages[""] must be a JSON object.');
38
+ }
39
+ const rootDirect = new Set();
40
+ if (root !== undefined) {
41
+ for (const section of directDependencySections) {
42
+ const declarations = root[section];
43
+ if (declarations === undefined) {
44
+ continue;
45
+ }
46
+ if (!isRecord(declarations)) {
47
+ return invalid(`packages[""].${section} must be a JSON object.`);
48
+ }
49
+ for (const name of Object.keys(declarations)) {
50
+ rootDirect.add(name);
51
+ }
52
+ }
53
+ }
54
+ const packages = new Map();
55
+ for (const [path, descriptor] of Object.entries(value.packages)) {
56
+ const name = packageNameAt(path);
57
+ if (name === undefined) {
58
+ continue;
59
+ }
60
+ if (!isRecord(descriptor)) {
61
+ return invalid(`packages[${JSON.stringify(path)}] must be a JSON object.`);
62
+ }
63
+ // npm workspaces and local links are represented as symlinks, not resolved external packages.
64
+ if (descriptor.link === true) {
65
+ continue;
66
+ }
67
+ if (typeof descriptor.version !== "string" || descriptor.version.length === 0) {
68
+ return invalid(`packages[${JSON.stringify(path)}].version must be a non-empty string.`);
69
+ }
70
+ packages.set(path, {
71
+ path,
72
+ name,
73
+ version: descriptor.version,
74
+ rootDirect: path === `node_modules/${name}` && rootDirect.has(name),
75
+ });
76
+ }
77
+ return { ok: true, packages };
78
+ }
79
+ }
80
+ function packageNameAt(path) {
81
+ const marker = "node_modules/";
82
+ const markerIndex = path.lastIndexOf(marker);
83
+ if (markerIndex === -1 || (markerIndex > 0 && path[markerIndex - 1] !== "/")) {
84
+ return undefined;
85
+ }
86
+ const name = path.slice(markerIndex + marker.length);
87
+ return /^(?:@[^/]+\/)?[^/]+$/.test(name) ? name : undefined;
88
+ }
89
+ //# sourceMappingURL=npm-package-lock-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"npm-package-lock-parser.js","sourceRoot":"","sources":["../../../src/infrastructure/npm/npm-package-lock-parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { PnpmLockParseResult, PnpmLockParser } from "../../application/ports/pnpm-lock-parser.js";
2
+ /** pnpm v9의 프로젝트 문서만 읽는다. 앞의 환경 문서를 프로젝트 dependency로 합치지 않는다. */
3
+ export declare class PnpmYamlLockParser implements PnpmLockParser {
4
+ parse(content: string): PnpmLockParseResult;
5
+ }
6
+ //# sourceMappingURL=pnpm-lock-parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pnpm-lock-parser.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/pnpm/pnpm-lock-parser.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAEV,mBAAmB,EACnB,cAAc,EACf,MAAM,6CAA6C,CAAC;AAQrD,iEAAiE;AACjE,qBAAa,kBAAmB,YAAW,cAAc;IAChD,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,mBAAmB;CA+DnD"}
@@ -0,0 +1,122 @@
1
+ import { parseAllDocuments } from "yaml";
2
+ import { invalidParseResult as invalid } from "../../application/ports/parse-failure.js";
3
+ import { isRecord } from "../../domain/value-guards.js";
4
+ const directSections = ["dependencies", "devDependencies", "optionalDependencies"];
5
+ const packageNamePattern = /^(?:@[^/@]+\/)?[^/@]+$/;
6
+ const versionPattern = /^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/;
7
+ /** pnpm v9의 프로젝트 문서만 읽는다. 앞의 환경 문서를 프로젝트 dependency로 합치지 않는다. */
8
+ export class PnpmYamlLockParser {
9
+ parse(content) {
10
+ try {
11
+ const documents = parseAllDocuments(content, { logLevel: "error", stringKeys: true });
12
+ if (documents.length === 0) {
13
+ return invalid("The file does not contain a YAML document.");
14
+ }
15
+ if (documents.length > 2) {
16
+ return unsupported("Expected one project document, optionally preceded by one environment document.");
17
+ }
18
+ const values = [];
19
+ for (const document of documents) {
20
+ if (document.errors.length > 0) {
21
+ return invalid(`The file is not valid YAML: ${document.errors[0]?.message ?? "unknown error"}`);
22
+ }
23
+ const value = document.toJS({ maxAliasCount: 100 });
24
+ if (!isRecord(value)) {
25
+ return invalid("Each lockfile document must be a YAML mapping.");
26
+ }
27
+ values.push(value);
28
+ const version = validateVersion(value.lockfileVersion);
29
+ if (version !== undefined) {
30
+ return version;
31
+ }
32
+ }
33
+ const project = values.at(-1);
34
+ if (project === undefined || !isRecord(project.importers)) {
35
+ return invalid("The project document must contain an importers mapping.");
36
+ }
37
+ if (project.packages !== undefined && !isRecord(project.packages)) {
38
+ return invalid("packages must be a YAML mapping.");
39
+ }
40
+ const direct = parseRootDirectPackages(project.importers);
41
+ if (!direct.ok) {
42
+ return direct;
43
+ }
44
+ const packages = new Map();
45
+ for (const [id, descriptor] of Object.entries(project.packages ?? {})) {
46
+ if (!isRecord(descriptor)) {
47
+ return invalid(`packages[${JSON.stringify(id)}] must be a YAML mapping.`);
48
+ }
49
+ const packageId = parseRegistryPackageId(id);
50
+ if (packageId === undefined) {
51
+ // file:, link:, Git 등 레지스트리 버전으로 표현할 수 없는 항목은 제외한다.
52
+ continue;
53
+ }
54
+ packages.set(id, {
55
+ id,
56
+ ...packageId,
57
+ rootDirect: direct.ids.has(id),
58
+ });
59
+ }
60
+ return { ok: true, packages };
61
+ }
62
+ catch (error) {
63
+ const reason = error instanceof Error ? error.message : String(error);
64
+ return invalid(`The YAML parser could not read the lockfile: ${reason}`);
65
+ }
66
+ }
67
+ }
68
+ function validateVersion(value) {
69
+ if (typeof value !== "string" && typeof value !== "number") {
70
+ return invalid("lockfileVersion must be a string or number.");
71
+ }
72
+ if (!/^9(?:\.\d+)?$/.test(String(value))) {
73
+ return unsupported(`Only pnpm lockfile version 9 is supported; found ${String(value)}.`);
74
+ }
75
+ return undefined;
76
+ }
77
+ function parseRootDirectPackages(importers) {
78
+ const root = importers["."];
79
+ if (root === undefined) {
80
+ return { ok: true, ids: new Set() };
81
+ }
82
+ if (!isRecord(root)) {
83
+ return invalid('importers["."] must be a YAML mapping.');
84
+ }
85
+ const ids = new Set();
86
+ for (const section of directSections) {
87
+ const dependencies = root[section];
88
+ if (dependencies === undefined) {
89
+ continue;
90
+ }
91
+ if (!isRecord(dependencies)) {
92
+ return invalid(`importers["."].${section} must be a YAML mapping.`);
93
+ }
94
+ for (const [name, descriptor] of Object.entries(dependencies)) {
95
+ if (!isRecord(descriptor) || typeof descriptor.version !== "string") {
96
+ return invalid(`importers["."].${section}[${JSON.stringify(name)}].version must be a string.`);
97
+ }
98
+ const resolvedVersion = descriptor.version.split("(", 1)[0];
99
+ if (packageNamePattern.test(name) &&
100
+ resolvedVersion !== undefined &&
101
+ versionPattern.test(resolvedVersion)) {
102
+ ids.add(`${name}@${resolvedVersion}`);
103
+ }
104
+ }
105
+ }
106
+ return { ok: true, ids };
107
+ }
108
+ function parseRegistryPackageId(id) {
109
+ const separator = id.lastIndexOf("@");
110
+ if (separator <= 0) {
111
+ return undefined;
112
+ }
113
+ const name = id.slice(0, separator);
114
+ const version = id.slice(separator + 1);
115
+ return packageNamePattern.test(name) && versionPattern.test(version)
116
+ ? { name, version }
117
+ : undefined;
118
+ }
119
+ function unsupported(reason) {
120
+ return { ok: false, kind: "unsupported", reason };
121
+ }
122
+ //# sourceMappingURL=pnpm-lock-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pnpm-lock-parser.js","sourceRoot":"","sources":["../../../src/infrastructure/pnpm/pnpm-lock-parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { PnpmWorkspaceParseResult, PnpmWorkspaceParser } from "../../application/ports/pnpm-workspace-parser.js";
2
+ /** pnpm-workspace.yaml의 packages 필드와 지원 가능한 glob 부분집합을 해석한다. */
3
+ export declare class PnpmYamlWorkspaceParser implements PnpmWorkspaceParser {
4
+ parse(content: string | undefined): PnpmWorkspaceParseResult;
5
+ }
6
+ //# sourceMappingURL=pnpm-workspace-parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pnpm-workspace-parser.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/pnpm/pnpm-workspace-parser.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,wBAAwB,EACxB,mBAAmB,EACpB,MAAM,kDAAkD,CAAC;AAG1D,gEAAgE;AAChE,qBAAa,uBAAwB,YAAW,mBAAmB;IAC1D,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,wBAAwB;CAyDpE"}
@@ -0,0 +1,62 @@
1
+ import { parseAllDocuments } from "yaml";
2
+ import { invalidParseResult as invalid } from "../../application/ports/parse-failure.js";
3
+ import { isRecord } from "../../domain/value-guards.js";
4
+ /** pnpm-workspace.yaml의 packages 필드와 지원 가능한 glob 부분집합을 해석한다. */
5
+ export class PnpmYamlWorkspaceParser {
6
+ parse(content) {
7
+ if (content === undefined || content.trim().length === 0) {
8
+ return { ok: true, patterns: { includes: [], excludes: [] } };
9
+ }
10
+ try {
11
+ const documents = parseAllDocuments(content, { stringKeys: true, logLevel: "error" });
12
+ if (documents.length !== 1 || documents[0] === undefined) {
13
+ return invalid("Expected one YAML document.");
14
+ }
15
+ const document = documents[0];
16
+ if (document.errors.length > 0) {
17
+ return invalid(`The file is not valid YAML: ${document.errors[0]?.message ?? "unknown error"}`);
18
+ }
19
+ const value = document.toJS({ maxAliasCount: 100 });
20
+ if (!isRecord(value))
21
+ return invalid("The root value must be a YAML mapping.");
22
+ if (value.packages === undefined)
23
+ return { ok: true, patterns: { includes: [], excludes: [] } };
24
+ if (!Array.isArray(value.packages))
25
+ return invalid("packages must be an array of paths.");
26
+ const includes = [];
27
+ const excludes = [];
28
+ for (const raw of value.packages) {
29
+ if (typeof raw !== "string" || raw.trim().length === 0) {
30
+ return invalid("Each package path must be a non-empty string.");
31
+ }
32
+ const excluded = raw.startsWith("!");
33
+ const pattern = raw
34
+ .slice(excluded ? 1 : 0)
35
+ .replace(/^(\.\/)+/u, "")
36
+ .replace(/\/+$/u, "");
37
+ if (pattern.length === 0 || pattern.startsWith("/") || pattern.split("/").includes("..")) {
38
+ return invalid(`Invalid workspace path: ${raw}.`);
39
+ }
40
+ if (/[{}[\]\\!]/u.test(pattern)) {
41
+ return {
42
+ ok: false,
43
+ kind: "unsupported",
44
+ reason: `Unsupported workspace pattern: ${raw}. Only *, **, and ? globs are supported.`,
45
+ };
46
+ }
47
+ (excluded ? excludes : includes).push(pattern);
48
+ }
49
+ return {
50
+ ok: true,
51
+ patterns: {
52
+ includes: [...new Set(includes)].sort(),
53
+ excludes: [...new Set(excludes)].sort(),
54
+ },
55
+ };
56
+ }
57
+ catch (error) {
58
+ return invalid(`The YAML parser could not read the configuration: ${error instanceof Error ? error.message : String(error)}`);
59
+ }
60
+ }
61
+ }
62
+ //# sourceMappingURL=pnpm-workspace-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pnpm-workspace-parser.js","sourceRoot":"","sources":["../../../src/infrastructure/pnpm/pnpm-workspace-parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { ModuleReferenceExtractionResult, ModuleReferenceExtractor } from "../../application/ports/module-reference-extractor.js";
2
+ /** JS/TS AST에서 명시적 import, re-export, require와 동적 import의 문자열 인자를 수집한다. */
3
+ export declare class PackageModuleReferenceExtractor implements ModuleReferenceExtractor {
4
+ supports(path: string): boolean;
5
+ extract(path: string, source: string): ModuleReferenceExtractionResult;
6
+ }
7
+ //# sourceMappingURL=package-module-reference-extractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package-module-reference-extractor.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/typescript/package-module-reference-extractor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,+BAA+B,EAC/B,wBAAwB,EACzB,MAAM,uDAAuD,CAAC;AAI/D,2EAA2E;AAC3E,qBAAa,+BAAgC,YAAW,wBAAwB;IACvE,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI/B,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,+BAA+B;CAoD9E"}
@@ -0,0 +1,68 @@
1
+ import ts from "typescript";
2
+ const sourceExtension = /\.(?:[cm]?[jt]s|[jt]sx)$/u;
3
+ /** JS/TS AST에서 명시적 import, re-export, require와 동적 import의 문자열 인자를 수집한다. */
4
+ export class PackageModuleReferenceExtractor {
5
+ supports(path) {
6
+ return sourceExtension.test(path);
7
+ }
8
+ extract(path, source) {
9
+ const result = ts.transpileModule(source, {
10
+ fileName: path,
11
+ reportDiagnostics: true,
12
+ compilerOptions: { target: ts.ScriptTarget.Latest, jsx: ts.JsxEmit.ReactJSX },
13
+ });
14
+ const error = result.diagnostics?.find((diagnostic) => diagnostic.category === ts.DiagnosticCategory.Error);
15
+ if (error !== undefined) {
16
+ return {
17
+ kind: "unavailable",
18
+ reason: ts.flattenDiagnosticMessageText(error.messageText, " "),
19
+ };
20
+ }
21
+ const sourceFile = ts.createSourceFile(path, source, ts.ScriptTarget.Latest, true, scriptKind(path));
22
+ const specifiers = new Set();
23
+ let hasDynamicSpecifier = false;
24
+ const visit = (node) => {
25
+ if ((ts.isImportDeclaration(node) || ts.isExportDeclaration(node)) &&
26
+ node.moduleSpecifier !== undefined &&
27
+ ts.isStringLiteralLike(node.moduleSpecifier)) {
28
+ specifiers.add(node.moduleSpecifier.text);
29
+ }
30
+ else if (ts.isImportEqualsDeclaration(node) &&
31
+ ts.isExternalModuleReference(node.moduleReference) &&
32
+ node.moduleReference.expression !== undefined &&
33
+ ts.isStringLiteralLike(node.moduleReference.expression)) {
34
+ specifiers.add(node.moduleReference.expression.text);
35
+ }
36
+ else if (ts.isCallExpression(node) && isModuleLoad(node.expression)) {
37
+ const argument = node.arguments[0];
38
+ if (argument !== undefined && ts.isStringLiteralLike(argument)) {
39
+ specifiers.add(argument.text);
40
+ }
41
+ else {
42
+ hasDynamicSpecifier = true;
43
+ }
44
+ }
45
+ ts.forEachChild(node, visit);
46
+ };
47
+ visit(sourceFile);
48
+ return { kind: "success", specifiers: [...specifiers].sort(), hasDynamicSpecifier };
49
+ }
50
+ }
51
+ function isModuleLoad(expression) {
52
+ return (expression.kind === ts.SyntaxKind.ImportKeyword ||
53
+ (ts.isIdentifier(expression) && expression.text === "require") ||
54
+ (ts.isPropertyAccessExpression(expression) &&
55
+ ts.isIdentifier(expression.expression) &&
56
+ expression.expression.text === "require" &&
57
+ expression.name.text === "resolve"));
58
+ }
59
+ function scriptKind(path) {
60
+ if (path.endsWith(".tsx"))
61
+ return ts.ScriptKind.TSX;
62
+ if (path.endsWith(".jsx"))
63
+ return ts.ScriptKind.JSX;
64
+ if (/\.(?:c|m)?js$/u.test(path))
65
+ return ts.ScriptKind.JS;
66
+ return ts.ScriptKind.TS;
67
+ }
68
+ //# sourceMappingURL=package-module-reference-extractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package-module-reference-extractor.js","sourceRoot":"","sources":["../../../src/infrastructure/typescript/package-module-reference-extractor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import ts from "typescript";
2
+ import type { ProjectFileSource } from "../../application/ports/project-file-source.js";
3
+ import type { ImpactAnalysisIssue } from "../../domain/impact.js";
4
+ import type { AnalysisTarget } from "../../domain/report.js";
5
+ export declare const virtualProjectRoot = "/__intentpatch_project__";
6
+ export declare function virtualProjectPath(path: string): string;
7
+ export interface LoadedTypeScriptConfigs {
8
+ readonly optionsByPath: ReadonlyMap<string, ts.CompilerOptions>;
9
+ readonly issues: readonly ImpactAnalysisIssue[];
10
+ }
11
+ /** Git snapshot의 설정만 사용해 TypeScript 경로 별칭을 읽는다. */
12
+ export declare class TypeScriptConfigLoader {
13
+ private readonly files;
14
+ constructor(files: ProjectFileSource);
15
+ load(target: AnalysisTarget, repositoryPaths: readonly string[], configPaths: readonly string[]): Promise<LoadedTypeScriptConfigs>;
16
+ }
17
+ //# sourceMappingURL=typescript-config-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typescript-config-loader.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/typescript/typescript-config-loader.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gDAAgD,CAAC;AACxF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAG7D,eAAO,MAAM,kBAAkB,6BAA6B,CAAC;AAE7D,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,aAAa,EAAE,WAAW,CAAC,MAAM,EAAE,EAAE,CAAC,eAAe,CAAC,CAAC;IAChE,QAAQ,CAAC,MAAM,EAAE,SAAS,mBAAmB,EAAE,CAAC;CACjD;AAED,mDAAmD;AACnD,qBAAa,sBAAsB;IACd,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAAL,KAAK,EAAE,iBAAiB;IAE/C,IAAI,CACf,MAAM,EAAE,cAAc,EACtB,eAAe,EAAE,SAAS,MAAM,EAAE,EAClC,WAAW,EAAE,SAAS,MAAM,EAAE,GAC7B,OAAO,CAAC,uBAAuB,CAAC;CAyFpC"}
@@ -0,0 +1,97 @@
1
+ import { posix } from "node:path";
2
+ import ts from "typescript";
3
+ import { isRecord } from "../../domain/value-guards.js";
4
+ export const virtualProjectRoot = "/__intentpatch_project__";
5
+ export function virtualProjectPath(path) {
6
+ return posix.join(virtualProjectRoot, path);
7
+ }
8
+ /** Git snapshot의 설정만 사용해 TypeScript 경로 별칭을 읽는다. */
9
+ export class TypeScriptConfigLoader {
10
+ files;
11
+ constructor(files) {
12
+ this.files = files;
13
+ }
14
+ async load(target, repositoryPaths, configPaths) {
15
+ const listedPaths = new Set(repositoryPaths);
16
+ const configContents = new Map();
17
+ const parsedConfigs = new Map();
18
+ const visited = new Set();
19
+ const issues = [];
20
+ const collect = async (path) => {
21
+ if (visited.has(path)) {
22
+ return;
23
+ }
24
+ visited.add(path);
25
+ const file = await this.files.read(target, path);
26
+ if (file.kind !== "success") {
27
+ issues.push({
28
+ path,
29
+ reason: file.kind === "missing" ? "TypeScript config is missing" : file.reason,
30
+ });
31
+ return;
32
+ }
33
+ const parsed = ts.parseConfigFileTextToJson(path, file.content);
34
+ if (parsed.error !== undefined || !isRecord(parsed.config)) {
35
+ issues.push({
36
+ path,
37
+ reason: parsed.error === undefined
38
+ ? "TypeScript config must be an object"
39
+ : ts.flattenDiagnosticMessageText(parsed.error.messageText, "\n"),
40
+ });
41
+ return;
42
+ }
43
+ configContents.set(virtualProjectPath(path), file.content);
44
+ parsedConfigs.set(path, parsed.config);
45
+ const extensions = parsed.config.extends;
46
+ const references = Array.isArray(extensions) ? extensions : [extensions];
47
+ for (const reference of references) {
48
+ if (typeof reference !== "string" || !reference.startsWith(".")) {
49
+ continue;
50
+ }
51
+ const extendedPath = resolveExtendedConfig(path, reference, listedPaths);
52
+ if (extendedPath !== undefined) {
53
+ await collect(extendedPath);
54
+ }
55
+ }
56
+ };
57
+ for (const path of configPaths) {
58
+ await collect(path);
59
+ }
60
+ const host = {
61
+ useCaseSensitiveFileNames: true,
62
+ readDirectory: () => [],
63
+ fileExists: (path) => configContents.has(path),
64
+ readFile: (path) => configContents.get(path),
65
+ };
66
+ const optionsByPath = new Map();
67
+ for (const path of configPaths) {
68
+ const config = parsedConfigs.get(path);
69
+ if (config === undefined) {
70
+ continue;
71
+ }
72
+ const parsed = ts.parseJsonConfigFileContent(config, host, posix.dirname(virtualProjectPath(path)), undefined, virtualProjectPath(path));
73
+ optionsByPath.set(path, parsed.options);
74
+ for (const diagnostic of parsed.errors) {
75
+ // 파일 목록은 사용하지 않으므로 빈 readDirectory에 따른 입력 없음 진단만 제외한다.
76
+ if (diagnostic.code !== 18003) {
77
+ issues.push({
78
+ path,
79
+ reason: ts
80
+ .flattenDiagnosticMessageText(diagnostic.messageText, "\n")
81
+ .replaceAll(`${virtualProjectRoot}/`, ""),
82
+ });
83
+ }
84
+ }
85
+ }
86
+ return { optionsByPath, issues };
87
+ }
88
+ }
89
+ function resolveExtendedConfig(configPath, reference, listedPaths) {
90
+ const basePath = posix.normalize(posix.join(posix.dirname(configPath), reference));
91
+ if (basePath === ".." || basePath.startsWith("../") || posix.isAbsolute(basePath)) {
92
+ return undefined;
93
+ }
94
+ const candidates = [basePath, `${basePath}.json`, posix.join(basePath, "tsconfig.json")];
95
+ return candidates.find((candidate) => listedPaths.has(candidate));
96
+ }
97
+ //# sourceMappingURL=typescript-config-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typescript-config-loader.js","sourceRoot":"","sources":["../../../src/infrastructure/typescript/typescript-config-loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { ModuleAliasResolver, PreparedModuleAliasResolver } from "../../application/ports/module-alias-resolver.js";
2
+ import type { ProjectFileSource } from "../../application/ports/project-file-source.js";
3
+ import type { AnalysisTarget } from "../../domain/report.js";
4
+ /** 가장 가까운 tsconfig/jsconfig의 paths·baseUrl을 Git snapshot 안에서 해석한다. */
5
+ export declare class TypeScriptModuleAliasResolver implements ModuleAliasResolver {
6
+ private readonly files;
7
+ constructor(files: ProjectFileSource);
8
+ prepare(target: AnalysisTarget, repositoryPaths: readonly string[], sourcePaths: ReadonlySet<string>): Promise<PreparedModuleAliasResolver>;
9
+ }
10
+ //# sourceMappingURL=typescript-module-alias-resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typescript-module-alias-resolver.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/typescript/typescript-module-alias-resolver.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,mBAAmB,EACnB,2BAA2B,EAC5B,MAAM,kDAAkD,CAAC;AAC1D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gDAAgD,CAAC;AACxF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAO7D,sEAAsE;AACtE,qBAAa,6BAA8B,YAAW,mBAAmB;IACpD,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAAL,KAAK,EAAE,iBAAiB;IAE/C,OAAO,CAClB,MAAM,EAAE,cAAc,EACtB,eAAe,EAAE,SAAS,MAAM,EAAE,EAClC,WAAW,EAAE,WAAW,CAAC,MAAM,CAAC,GAC/B,OAAO,CAAC,2BAA2B,CAAC;CAqDxC"}
@@ -0,0 +1,78 @@
1
+ import { posix } from "node:path";
2
+ import ts from "typescript";
3
+ import { TypeScriptConfigLoader, virtualProjectPath, virtualProjectRoot, } from "./typescript-config-loader.js";
4
+ /** 가장 가까운 tsconfig/jsconfig의 paths·baseUrl을 Git snapshot 안에서 해석한다. */
5
+ export class TypeScriptModuleAliasResolver {
6
+ files;
7
+ constructor(files) {
8
+ this.files = files;
9
+ }
10
+ async prepare(target, repositoryPaths, sourcePaths) {
11
+ const configPaths = new Set(repositoryPaths.filter(isProjectConfig));
12
+ const configByImporter = new Map();
13
+ for (const importer of sourcePaths) {
14
+ const configPath = nearestConfig(importer, configPaths);
15
+ if (configPath !== undefined) {
16
+ configByImporter.set(importer, configPath);
17
+ }
18
+ }
19
+ const loaded = await new TypeScriptConfigLoader(this.files).load(target, repositoryPaths, [...new Set(configByImporter.values())].sort());
20
+ const virtualSources = new Set([...sourcePaths].map(virtualProjectPath));
21
+ const directories = sourceDirectories(virtualSources);
22
+ const host = {
23
+ fileExists: (path) => virtualSources.has(path),
24
+ readFile: () => undefined,
25
+ directoryExists: (path) => directories.has(path),
26
+ getCurrentDirectory: () => virtualProjectRoot,
27
+ realpath: (path) => path,
28
+ useCaseSensitiveFileNames: true,
29
+ };
30
+ return {
31
+ issues: loaded.issues,
32
+ resolve: (importer, specifier) => {
33
+ const configPath = configByImporter.get(importer);
34
+ const options = configPath === undefined ? undefined : loaded.optionsByPath.get(configPath);
35
+ if (options === undefined ||
36
+ (options.paths === undefined && options.baseUrl === undefined)) {
37
+ return undefined;
38
+ }
39
+ const resolved = ts.resolveModuleName(specifier, virtualProjectPath(importer), options, host).resolvedModule?.resolvedFileName;
40
+ if (resolved === undefined) {
41
+ return undefined;
42
+ }
43
+ const path = posix.relative(virtualProjectRoot, resolved);
44
+ return sourcePaths.has(path) ? path : undefined;
45
+ },
46
+ };
47
+ }
48
+ }
49
+ function isProjectConfig(path) {
50
+ return posix.basename(path) === "tsconfig.json" || posix.basename(path) === "jsconfig.json";
51
+ }
52
+ function nearestConfig(importer, configPaths) {
53
+ let directory = posix.dirname(importer);
54
+ while (true) {
55
+ for (const name of ["tsconfig.json", "jsconfig.json"]) {
56
+ const candidate = directory === "." ? name : posix.join(directory, name);
57
+ if (configPaths.has(candidate)) {
58
+ return candidate;
59
+ }
60
+ }
61
+ if (directory === ".") {
62
+ return undefined;
63
+ }
64
+ directory = posix.dirname(directory);
65
+ }
66
+ }
67
+ function sourceDirectories(virtualSources) {
68
+ const directories = new Set([virtualProjectRoot]);
69
+ for (const source of virtualSources) {
70
+ let directory = posix.dirname(source);
71
+ while (!directories.has(directory)) {
72
+ directories.add(directory);
73
+ directory = posix.dirname(directory);
74
+ }
75
+ }
76
+ return directories;
77
+ }
78
+ //# sourceMappingURL=typescript-module-alias-resolver.js.map