vh-dev-helper 1.0.0 → 1.0.2

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 (192) hide show
  1. package/dist/app.d.ts +8 -0
  2. package/dist/app.js +24 -0
  3. package/dist/app.js.map +1 -0
  4. package/dist/bin/index.js +6 -2
  5. package/dist/bin/index.js.map +1 -0
  6. package/dist/features/git/git.controller.d.ts +24 -0
  7. package/dist/features/git/git.controller.js +154 -0
  8. package/dist/features/git/git.controller.js.map +1 -0
  9. package/dist/features/git/git.route.d.ts +20 -0
  10. package/dist/features/git/git.route.js +132 -0
  11. package/dist/features/git/git.route.js.map +1 -0
  12. package/dist/features/git/git.service.d.ts +14 -0
  13. package/dist/features/git/git.service.js +342 -0
  14. package/dist/features/git/git.service.js.map +1 -0
  15. package/dist/features/logs/logs.route.d.ts +4 -0
  16. package/dist/features/logs/logs.route.js +50 -0
  17. package/dist/features/logs/logs.route.js.map +1 -0
  18. package/dist/features/logs/logs.service.d.ts +1 -0
  19. package/dist/features/logs/logs.service.js +3 -0
  20. package/dist/features/logs/logs.service.js.map +1 -0
  21. package/dist/features/logs/logs.socket.d.ts +16 -0
  22. package/dist/features/logs/logs.socket.js +133 -0
  23. package/dist/features/logs/logs.socket.js.map +1 -0
  24. package/dist/features/logs/logs.store.d.ts +1 -0
  25. package/dist/features/logs/logs.store.js +3 -0
  26. package/dist/features/logs/logs.store.js.map +1 -0
  27. package/dist/features/logs/logs.types.d.ts +1 -0
  28. package/dist/features/logs/logs.types.js +3 -0
  29. package/dist/features/logs/logs.types.js.map +1 -0
  30. package/dist/shared/config/config.d.ts +1 -0
  31. package/dist/shared/config/config.js +3 -0
  32. package/dist/shared/config/config.js.map +1 -0
  33. package/dist/shared/config/config.types.d.ts +1 -0
  34. package/dist/shared/config/config.types.js +3 -0
  35. package/dist/shared/config/config.types.js.map +1 -0
  36. package/dist/shared/config/defaults.d.ts +1 -0
  37. package/dist/shared/config/defaults.js +3 -0
  38. package/dist/shared/config/defaults.js.map +1 -0
  39. package/dist/shared/constants/env.constants.d.ts +1 -0
  40. package/dist/shared/constants/env.constants.js +3 -0
  41. package/dist/shared/constants/env.constants.js.map +1 -0
  42. package/dist/shared/errors/base.error.d.ts +1 -0
  43. package/dist/shared/errors/base.error.js +3 -0
  44. package/dist/shared/errors/base.error.js.map +1 -0
  45. package/dist/shared/errors/cli.error.d.ts +1 -0
  46. package/dist/shared/errors/cli.error.js +3 -0
  47. package/dist/shared/errors/cli.error.js.map +1 -0
  48. package/dist/shared/errors/runtine.error.d.ts +1 -0
  49. package/dist/shared/errors/runtine.error.js +3 -0
  50. package/dist/shared/errors/runtine.error.js.map +1 -0
  51. package/dist/shared/events/event-bus.d.ts +1 -0
  52. package/dist/shared/events/event-bus.js +3 -0
  53. package/dist/shared/events/event-bus.js.map +1 -0
  54. package/dist/shared/events/events.types.d.ts +1 -0
  55. package/dist/shared/events/events.types.js +3 -0
  56. package/dist/shared/events/events.types.js.map +1 -0
  57. package/dist/shared/helpers/gitParsers/parser.controller.d.ts +26 -0
  58. package/dist/shared/helpers/gitParsers/parser.controller.js +169 -0
  59. package/dist/shared/helpers/gitParsers/parser.controller.js.map +1 -0
  60. package/dist/shared/helpers/gitParsers/parser.services.d.ts +29 -0
  61. package/dist/shared/helpers/gitParsers/parser.services.js +368 -0
  62. package/dist/shared/helpers/gitParsers/parser.services.js.map +1 -0
  63. package/dist/shared/helpers/gitParsers/parser.types.d.ts +83 -0
  64. package/dist/shared/helpers/gitParsers/parser.types.js +22 -0
  65. package/dist/shared/helpers/gitParsers/parser.types.js.map +1 -0
  66. package/dist/shared/helpers/logger/logger.d.ts +1 -0
  67. package/dist/shared/helpers/logger/logger.js +3 -0
  68. package/dist/shared/helpers/logger/logger.js.map +1 -0
  69. package/dist/shared/helpers/logger/logger.types.d.ts +1 -0
  70. package/dist/shared/helpers/logger/logger.types.js +3 -0
  71. package/dist/shared/helpers/logger/logger.types.js.map +1 -0
  72. package/dist/shared/helpers/output/index.d.ts +19 -0
  73. package/dist/shared/helpers/output/index.js +78 -0
  74. package/dist/shared/helpers/output/index.js.map +1 -0
  75. package/dist/shared/helpers/prompt/prompt.d.ts +11 -0
  76. package/dist/shared/helpers/prompt/prompt.js +81 -0
  77. package/dist/shared/helpers/prompt/prompt.js.map +1 -0
  78. package/dist/shared/helpers/prompt/prompt.types.d.ts +40 -0
  79. package/dist/shared/helpers/prompt/prompt.types.js +3 -0
  80. package/dist/shared/helpers/prompt/prompt.types.js.map +1 -0
  81. package/dist/shared/helpers/shell/exec.d.ts +15 -0
  82. package/dist/shared/helpers/shell/exec.js +30 -0
  83. package/dist/shared/helpers/shell/exec.js.map +1 -0
  84. package/dist/shared/helpers/shell/spawn.d.ts +1 -0
  85. package/dist/shared/helpers/shell/spawn.js +3 -0
  86. package/dist/shared/helpers/shell/spawn.js.map +1 -0
  87. package/dist/shared/types/common.types.d.ts +1 -0
  88. package/dist/shared/types/common.types.js +3 -0
  89. package/dist/shared/types/common.types.js.map +1 -0
  90. package/dist/shared/ui/stepProgress/index.d.ts +19 -0
  91. package/dist/shared/ui/stepProgress/index.js +100 -0
  92. package/dist/shared/ui/stepProgress/index.js.map +1 -0
  93. package/dist/shared/ui/writer/index.d.ts +6 -0
  94. package/dist/shared/ui/writer/index.js +36 -0
  95. package/dist/shared/ui/writer/index.js.map +1 -0
  96. package/package.json +35 -23
  97. package/dist/src/commands/dashbaord/index.d.ts +0 -2
  98. package/dist/src/commands/dashbaord/index.js +0 -38
  99. package/dist/src/commands/dashbaord/project.command.d.ts +0 -2
  100. package/dist/src/commands/dashbaord/project.command.js +0 -17
  101. package/dist/src/commands/git/bg.command.d.ts +0 -2
  102. package/dist/src/commands/git/bg.command.js +0 -17
  103. package/dist/src/commands/git/cleanup.command.d.ts +0 -2
  104. package/dist/src/commands/git/cleanup.command.js +0 -12
  105. package/dist/src/commands/git/cp.command.d.ts +0 -2
  106. package/dist/src/commands/git/cp.command.js +0 -68
  107. package/dist/src/commands/git/del.command.d.ts +0 -2
  108. package/dist/src/commands/git/del.command.js +0 -19
  109. package/dist/src/commands/git/fetch.command.d.ts +0 -2
  110. package/dist/src/commands/git/fetch.command.js +0 -12
  111. package/dist/src/commands/git/final.command.d.ts +0 -2
  112. package/dist/src/commands/git/final.command.js +0 -23
  113. package/dist/src/commands/git/ga.command.d.ts +0 -2
  114. package/dist/src/commands/git/ga.command.js +0 -22
  115. package/dist/src/commands/git/gcm.command.d.ts +0 -2
  116. package/dist/src/commands/git/gcm.command.js +0 -23
  117. package/dist/src/commands/git/gco.command.d.ts +0 -2
  118. package/dist/src/commands/git/gco.command.js +0 -27
  119. package/dist/src/commands/git/gcob.command.d.ts +0 -2
  120. package/dist/src/commands/git/gcob.command.js +0 -23
  121. package/dist/src/commands/git/gph.command.d.ts +0 -2
  122. package/dist/src/commands/git/gph.command.js +0 -29
  123. package/dist/src/commands/git/gpho.command.d.ts +0 -2
  124. package/dist/src/commands/git/gpho.command.js +0 -20
  125. package/dist/src/commands/git/gpl.command.d.ts +0 -2
  126. package/dist/src/commands/git/gpl.command.js +0 -33
  127. package/dist/src/commands/git/gplo.command.d.ts +0 -2
  128. package/dist/src/commands/git/gplo.command.js +0 -20
  129. package/dist/src/commands/git/gpu.command.d.ts +0 -2
  130. package/dist/src/commands/git/gpu.command.js +0 -23
  131. package/dist/src/commands/git/gr.command.d.ts +0 -2
  132. package/dist/src/commands/git/gr.command.js +0 -20
  133. package/dist/src/commands/git/graph.command.d.ts +0 -2
  134. package/dist/src/commands/git/graph.command.js +0 -12
  135. package/dist/src/commands/git/gs.command.d.ts +0 -2
  136. package/dist/src/commands/git/gs.command.js +0 -23
  137. package/dist/src/commands/git/index.d.ts +0 -2
  138. package/dist/src/commands/git/index.js +0 -52
  139. package/dist/src/commands/git/init.command.d.ts +0 -2
  140. package/dist/src/commands/git/init.command.js +0 -12
  141. package/dist/src/commands/git/merge.command.d.ts +0 -2
  142. package/dist/src/commands/git/merge.command.js +0 -13
  143. package/dist/src/commands/git/sync.command.d.ts +0 -2
  144. package/dist/src/commands/git/sync.command.js +0 -12
  145. package/dist/src/commands/git/undo.command.d.ts +0 -2
  146. package/dist/src/commands/git/undo.command.js +0 -21
  147. package/dist/src/commands/git/untrack.command.d.ts +0 -2
  148. package/dist/src/commands/git/untrack.command.js +0 -27
  149. package/dist/src/commands/index.d.ts +0 -1
  150. package/dist/src/commands/index.js +0 -15
  151. package/dist/src/commands/network/discover.command.d.ts +0 -2
  152. package/dist/src/commands/network/discover.command.js +0 -24
  153. package/dist/src/commands/network/index.d.ts +0 -2
  154. package/dist/src/commands/network/index.js +0 -47
  155. package/dist/src/commands/network/inspect.command.d.ts +0 -2
  156. package/dist/src/commands/network/inspect.command.js +0 -34
  157. package/dist/src/commands/network/ports.command.d.ts +0 -2
  158. package/dist/src/commands/network/ports.command.js +0 -27
  159. package/dist/src/commands/network/ssl.command.d.ts +0 -2
  160. package/dist/src/commands/network/ssl.command.js +0 -32
  161. package/dist/src/commands/network/trace.command.d.ts +0 -2
  162. package/dist/src/commands/network/trace.command.js +0 -30
  163. package/dist/src/core/helper/command.helper.d.ts +0 -1
  164. package/dist/src/core/helper/command.helper.js +0 -28
  165. package/dist/src/core/helper/git.helper.d.ts +0 -2
  166. package/dist/src/core/helper/git.helper.js +0 -58
  167. package/dist/src/core/helper/prompts.helper.d.ts +0 -5
  168. package/dist/src/core/helper/prompts.helper.js +0 -83
  169. package/dist/src/core/shell/exec.d.ts +0 -1
  170. package/dist/src/core/shell/exec.js +0 -38
  171. package/dist/src/dashboards/collectors/project/project.collector.d.ts +0 -9
  172. package/dist/src/dashboards/collectors/project/project.collector.js +0 -29
  173. package/dist/src/dashboards/project/backend/server/dashboard.bootstrap.d.ts +0 -6
  174. package/dist/src/dashboards/project/backend/server/dashboard.bootstrap.js +0 -45
  175. package/dist/src/dashboards/project/backend/server/dashboard.server.d.ts +0 -6
  176. package/dist/src/dashboards/project/backend/server/dashboard.server.js +0 -25
  177. package/dist/src/dashboards/project/backend/server/websocket.server.d.ts +0 -8
  178. package/dist/src/dashboards/project/backend/server/websocket.server.js +0 -28
  179. package/dist/src/dashboards/project/backend/services/git.service.d.ts +0 -9
  180. package/dist/src/dashboards/project/backend/services/git.service.js +0 -18
  181. package/dist/src/dashboards/project/backend/services/metrics.service.d.ts +0 -7
  182. package/dist/src/dashboards/project/backend/services/metrics.service.js +0 -54
  183. package/dist/src/dashboards/project/backend/services/project.service.d.ts +0 -10
  184. package/dist/src/dashboards/project/backend/services/project.service.js +0 -19
  185. package/dist/src/dashboards/project/backend/services/system.service.d.ts +0 -15
  186. package/dist/src/dashboards/project/backend/services/system.service.js +0 -42
  187. package/dist/src/dashboards/project/backend/wrapper/process.wrapper.d.ts +0 -13
  188. package/dist/src/dashboards/project/backend/wrapper/process.wrapper.js +0 -56
  189. package/dist/src/services/git/git.service.d.ts +0 -37
  190. package/dist/src/services/git/git.service.js +0 -303
  191. package/dist/src/services/network/network.service.d.ts +0 -23
  192. package/dist/src/services/network/network.service.js +0 -524
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=env.constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.constants.js","sourceRoot":"","sources":["../../../src/shared/constants/env.constants.ts"],"names":[],"mappings":""}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=base.error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.error.js","sourceRoot":"","sources":["../../../src/shared/errors/base.error.ts"],"names":[],"mappings":""}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=cli.error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.error.js","sourceRoot":"","sources":["../../../src/shared/errors/cli.error.ts"],"names":[],"mappings":""}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=runtine.error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtine.error.js","sourceRoot":"","sources":["../../../src/shared/errors/runtine.error.ts"],"names":[],"mappings":""}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=event-bus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-bus.js","sourceRoot":"","sources":["../../../src/shared/events/event-bus.ts"],"names":[],"mappings":""}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=events.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.types.js","sourceRoot":"","sources":["../../../src/shared/events/events.types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,26 @@
1
+ import { Option } from "@clack/prompts";
2
+ import { ExecResult } from "../shell/exec.ts";
3
+ import { GitBranch, GitChangedFile, GitCurrentBranch, GitStatus } from "./parser.types.ts";
4
+ export declare class GitParserController {
5
+ private lastFetchAt;
6
+ private readonly FETCH_TTL;
7
+ isRepository(): Promise<boolean>;
8
+ getRepositoryRoot(): Promise<string>;
9
+ getCurrentBranch(): Promise<string>;
10
+ getCurrentCommit(): Promise<string>;
11
+ getRemotes(): Promise<string[]>;
12
+ remoteBranchExists(branch: string, remote?: string): Promise<boolean>;
13
+ ensureUpstream(branch: string, remote?: string): Promise<ExecResult>;
14
+ getRemoteUrl(remote?: string): Promise<string>;
15
+ getBranches(type?: "all" | "local" | "remote" | "current"): Promise<GitBranch[]>;
16
+ getStatus(isFetch?: boolean): Promise<GitStatus>;
17
+ getFileIcon(file: GitChangedFile): string;
18
+ getFileStatus(file: GitChangedFile): string;
19
+ getFileLabel(file: GitChangedFile): string;
20
+ getFileHint(file: GitChangedFile): string;
21
+ getBranchLabel(branch: GitCurrentBranch): string;
22
+ getBranchHint(branch: GitCurrentBranch): string;
23
+ getFileSelectOptions(files: GitChangedFile[]): Option<string>[];
24
+ getStageableFiles(files: GitChangedFile[]): GitChangedFile[];
25
+ }
26
+ export declare const gitHelper: GitParserController;
@@ -0,0 +1,169 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.gitHelper = exports.GitParserController = void 0;
4
+ const exec_ts_1 = require("../shell/exec.js");
5
+ const parser_services_ts_1 = require("./parser.services.js");
6
+ class GitParserController {
7
+ lastFetchAt = 0;
8
+ FETCH_TTL = 20000;
9
+ async isRepository() {
10
+ const result = await (0, exec_ts_1.exec)("git rev-parse --is-inside-work-tree");
11
+ return result.success && result.stdout === "true";
12
+ }
13
+ async getRepositoryRoot() {
14
+ const result = await (0, exec_ts_1.exec)("git rev-parse --show-toplevel", {
15
+ throwOnError: true,
16
+ });
17
+ return result.stdout;
18
+ }
19
+ async getCurrentBranch() {
20
+ const result = await (0, exec_ts_1.exec)("git branch --show-current", {
21
+ throwOnError: true,
22
+ });
23
+ return result.stdout;
24
+ }
25
+ async getCurrentCommit() {
26
+ const result = await (0, exec_ts_1.exec)("git rev-parse HEAD", {
27
+ throwOnError: true,
28
+ });
29
+ return result.stdout;
30
+ }
31
+ async getRemotes() {
32
+ const result = await (0, exec_ts_1.exec)("git remote", {
33
+ throwOnError: true,
34
+ });
35
+ return result.stdout
36
+ .split("\n")
37
+ .map((remote) => remote.trim())
38
+ .filter(Boolean);
39
+ }
40
+ async remoteBranchExists(branch, remote = "origin") {
41
+ const result = await (0, exec_ts_1.exec)(`git ls-remote --heads ${remote} refs/heads/${branch}`, {
42
+ throwOnError: true,
43
+ });
44
+ return result.stdout.trim() !== "";
45
+ }
46
+ async ensureUpstream(branch, remote = "origin") {
47
+ const successResult = {
48
+ stdout: "",
49
+ stderr: "",
50
+ durationMs: 0,
51
+ success: true,
52
+ command: "",
53
+ };
54
+ const status = await this.getStatus();
55
+ // Already configured
56
+ if (status.currentBranch.upstream) {
57
+ return successResult;
58
+ }
59
+ const remoteBranch = `${remote}/${branch}`;
60
+ const remoteBranchExists = await this.remoteBranchExists(branch, remote);
61
+ if (!remoteBranchExists) {
62
+ return {
63
+ ...successResult,
64
+ success: false,
65
+ stderr: `Remote branch '${remoteBranch}' does not exist.`,
66
+ };
67
+ }
68
+ // Make sure the remote tracking ref exists locally.
69
+ const fetchResult = await (0, exec_ts_1.exec)(`git fetch ${remote}`);
70
+ if (!fetchResult.success) {
71
+ return fetchResult;
72
+ }
73
+ const upstreamResult = await (0, exec_ts_1.exec)(`git branch --set-upstream-to=${remoteBranch}`);
74
+ if (!upstreamResult.success) {
75
+ return upstreamResult;
76
+ }
77
+ return successResult;
78
+ }
79
+ async getRemoteUrl(remote = "origin") {
80
+ const result = await (0, exec_ts_1.exec)(`git remote get-url ${remote}`, {
81
+ throwOnError: true,
82
+ });
83
+ return result.stdout;
84
+ }
85
+ async getBranches(type = "all") {
86
+ const result = await (0, exec_ts_1.exec)(`git for-each-ref --format="%(HEAD)|%(refname:short)|%(refname)" refs/heads refs/remotes`, {
87
+ throwOnError: true,
88
+ });
89
+ const branches = result.stdout
90
+ .split("\n")
91
+ .filter(Boolean)
92
+ .map((line) => {
93
+ const [head, shortName, fullRef] = line.split("|");
94
+ return {
95
+ name: shortName,
96
+ current: head === "*",
97
+ remote: fullRef.startsWith("refs/remotes"),
98
+ fullRef,
99
+ };
100
+ })
101
+ // Ignore refs like origin/HEAD -> origin/main
102
+ .filter((branch) => !branch.fullRef.endsWith("/HEAD"))
103
+ .map(({ fullRef, ...branch }) => branch)
104
+ .sort((a, b) => {
105
+ // Current branch first
106
+ if (a.current)
107
+ return -1;
108
+ if (b.current)
109
+ return 1;
110
+ // Local branches before remote branches
111
+ if (a.remote !== b.remote) {
112
+ return a.remote ? 1 : -1;
113
+ }
114
+ // Alphabetical
115
+ return a.name.localeCompare(b.name);
116
+ });
117
+ switch (type) {
118
+ case "current":
119
+ return branches.filter((branch) => branch.current);
120
+ case "local":
121
+ return branches.filter((branch) => !branch.remote);
122
+ case "remote":
123
+ return branches.filter((branch) => branch.remote);
124
+ default:
125
+ return branches;
126
+ }
127
+ }
128
+ async getStatus(isFetch = false) {
129
+ if (isFetch) {
130
+ const now = Date.now();
131
+ if (now - this.lastFetchAt > this.FETCH_TTL) {
132
+ const result = await (0, exec_ts_1.exec)("git fetch");
133
+ if (result.success)
134
+ this.lastFetchAt = now;
135
+ }
136
+ }
137
+ const result = await (0, exec_ts_1.exec)("git status --porcelain=v2 --branch -z", {
138
+ throwOnError: true,
139
+ });
140
+ return parser_services_ts_1.GitParser.parseStatus(result.stdout);
141
+ }
142
+ getFileIcon(file) {
143
+ return parser_services_ts_1.GitDisplay.getFileIcon(file);
144
+ }
145
+ getFileStatus(file) {
146
+ return parser_services_ts_1.GitDisplay.getFileStatus(file);
147
+ }
148
+ getFileLabel(file) {
149
+ return parser_services_ts_1.GitDisplay.getFileLabel(file);
150
+ }
151
+ getFileHint(file) {
152
+ return parser_services_ts_1.GitDisplay.getFileHint(file);
153
+ }
154
+ getBranchLabel(branch) {
155
+ return parser_services_ts_1.GitDisplay.getBranchLabel(branch);
156
+ }
157
+ getBranchHint(branch) {
158
+ return parser_services_ts_1.GitDisplay.getBranchHint(branch);
159
+ }
160
+ getFileSelectOptions(files) {
161
+ return parser_services_ts_1.GitDisplay.getFileSelectOptions(files);
162
+ }
163
+ getStageableFiles(files) {
164
+ return parser_services_ts_1.GitStatusHelper.getStageableFiles(files);
165
+ }
166
+ }
167
+ exports.GitParserController = GitParserController;
168
+ exports.gitHelper = new GitParserController();
169
+ //# sourceMappingURL=parser.controller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.controller.js","sourceRoot":"","sources":["../../../../src/shared/helpers/gitParsers/parser.controller.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import { Option } from "@clack/prompts";
2
+ import { GitChangedFile, GitCurrentBranch, GitStatus, GitStatusSummary } from "./parser.types.ts";
3
+ export declare class GitParser {
4
+ static parseStatus(stdout: string): GitStatus;
5
+ private static parseBranchRecord;
6
+ private static parseNormalRecord;
7
+ private static parseRenameRecord;
8
+ private static parseUntrackedRecord;
9
+ private static parseIgnoredRecord;
10
+ private static parseUnmergedRecord;
11
+ private static parseFileStatus;
12
+ }
13
+ export declare class GitSummaryBuilder {
14
+ static build(files: GitChangedFile[]): GitStatusSummary;
15
+ private static countKind;
16
+ private static countStatus;
17
+ }
18
+ export declare class GitDisplay {
19
+ static getFileIcon(file: GitChangedFile): string;
20
+ static getFileStatus(file: GitChangedFile): string;
21
+ static getFileLabel(file: GitChangedFile): string;
22
+ static getFileHint(file: GitChangedFile): string;
23
+ static getBranchLabel(branch: GitCurrentBranch): string;
24
+ static getBranchHint(branch: GitCurrentBranch): string;
25
+ static getFileSelectOptions(files: GitChangedFile[]): Option<string>[];
26
+ }
27
+ export declare class GitStatusHelper {
28
+ static getStageableFiles(files: GitChangedFile[]): GitChangedFile[];
29
+ }
@@ -0,0 +1,368 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GitStatusHelper = exports.GitDisplay = exports.GitSummaryBuilder = exports.GitParser = void 0;
4
+ const parser_types_ts_1 = require("./parser.types.js");
5
+ // it parse the git plumbing command
6
+ class GitParser {
7
+ static parseStatus(stdout) {
8
+ const status = {
9
+ currentBranch: {
10
+ current: "",
11
+ detached: false,
12
+ ahead: 0,
13
+ behind: 0,
14
+ },
15
+ files: [],
16
+ summary: GitSummaryBuilder.build([]),
17
+ };
18
+ const records = stdout.split("\0").filter(Boolean);
19
+ for (let i = 0; i < records.length; i++) {
20
+ const record = records[i];
21
+ switch (record[0]) {
22
+ case "#":
23
+ this.parseBranchRecord(record, status.currentBranch);
24
+ break;
25
+ case "1":
26
+ status.files.push(this.parseNormalRecord(record));
27
+ break;
28
+ case "2": {
29
+ /**
30
+ * Rename/Copy records consume TWO records.
31
+ *
32
+ * record -> metadata + new path
33
+ * records[i+1] -> original path
34
+ */
35
+ const originalPath = records[++i];
36
+ status.files.push(this.parseRenameRecord(record, originalPath));
37
+ break;
38
+ }
39
+ case "?":
40
+ status.files.push(this.parseUntrackedRecord(record));
41
+ break;
42
+ case "!":
43
+ status.files.push(this.parseIgnoredRecord(record));
44
+ break;
45
+ case "u":
46
+ status.files.push(this.parseUnmergedRecord(record));
47
+ break;
48
+ }
49
+ }
50
+ status.summary = GitSummaryBuilder.build(status.files);
51
+ return status;
52
+ }
53
+ // --------------------------------------------------------------------------
54
+ // Branch
55
+ // --------------------------------------------------------------------------
56
+ static parseBranchRecord(record, branch) {
57
+ if (record.startsWith("# branch.head ")) {
58
+ const value = record.substring("# branch.head ".length);
59
+ branch.detached = value === "(detached)";
60
+ branch.current = branch.detached ? "" : value;
61
+ return;
62
+ }
63
+ if (record.startsWith("# branch.upstream ")) {
64
+ branch.upstream = record.substring("# branch.upstream ".length);
65
+ return;
66
+ }
67
+ if (record.startsWith("# branch.ab ")) {
68
+ const value = record.substring("# branch.ab ".length);
69
+ const [ahead, behind] = value.split(" ");
70
+ branch.ahead = Number(ahead.replace("+", ""));
71
+ branch.behind = Number(behind.replace("-", ""));
72
+ }
73
+ }
74
+ // --------------------------------------------------------------------------
75
+ // Normal
76
+ // --------------------------------------------------------------------------
77
+ static parseNormalRecord(record) {
78
+ /**
79
+ * Format
80
+ *
81
+ * 1 XY SUB M1 M2 M3 H1 H2 PATH
82
+ */
83
+ const parts = record.split(" ");
84
+ const xy = parts[1];
85
+ return {
86
+ kind: parser_types_ts_1.GitFileKind.Normal,
87
+ path: parts.slice(8).join(" "),
88
+ indexStatus: this.parseFileStatus(xy[0]),
89
+ workTreeStatus: this.parseFileStatus(xy[1]),
90
+ };
91
+ }
92
+ // --------------------------------------------------------------------------
93
+ // Rename / Copy
94
+ // --------------------------------------------------------------------------
95
+ static parseRenameRecord(record, originalPath) {
96
+ /**
97
+ * Format
98
+ *
99
+ * 2 XY SUB ... SCORE NEW_PATH
100
+ */
101
+ const parts = record.split(" ");
102
+ const xy = parts[1];
103
+ return {
104
+ kind: xy.includes("C") ? parser_types_ts_1.GitFileKind.Copy : parser_types_ts_1.GitFileKind.Rename,
105
+ path: parts.slice(9).join(" "),
106
+ originalPath,
107
+ indexStatus: this.parseFileStatus(xy[0]),
108
+ workTreeStatus: this.parseFileStatus(xy[1]),
109
+ };
110
+ }
111
+ // --------------------------------------------------------------------------
112
+ // Untracked
113
+ // --------------------------------------------------------------------------
114
+ static parseUntrackedRecord(record) {
115
+ return {
116
+ kind: parser_types_ts_1.GitFileKind.Untracked,
117
+ path: record.substring(2),
118
+ indexStatus: null,
119
+ workTreeStatus: null,
120
+ };
121
+ }
122
+ // --------------------------------------------------------------------------
123
+ // Ignored
124
+ // --------------------------------------------------------------------------
125
+ static parseIgnoredRecord(record) {
126
+ return {
127
+ kind: parser_types_ts_1.GitFileKind.Ignored,
128
+ path: record.substring(2),
129
+ indexStatus: null,
130
+ workTreeStatus: null,
131
+ };
132
+ }
133
+ // --------------------------------------------------------------------------
134
+ // Merge Conflict
135
+ // --------------------------------------------------------------------------
136
+ static parseUnmergedRecord(record) {
137
+ const parts = record.split(" ");
138
+ return {
139
+ kind: parser_types_ts_1.GitFileKind.Conflicted,
140
+ path: parts.at(-1) ?? "",
141
+ indexStatus: parser_types_ts_1.GitFileStatus.Unmerged,
142
+ workTreeStatus: parser_types_ts_1.GitFileStatus.Unmerged,
143
+ };
144
+ }
145
+ // --------------------------------------------------------------------------
146
+ // Status Parser
147
+ // --------------------------------------------------------------------------
148
+ static parseFileStatus(code) {
149
+ switch (code) {
150
+ case "M":
151
+ return parser_types_ts_1.GitFileStatus.Modified;
152
+ case "A":
153
+ return parser_types_ts_1.GitFileStatus.Added;
154
+ case "D":
155
+ return parser_types_ts_1.GitFileStatus.Deleted;
156
+ case "R":
157
+ return parser_types_ts_1.GitFileStatus.Renamed;
158
+ case "C":
159
+ return parser_types_ts_1.GitFileStatus.Copied;
160
+ case "U":
161
+ return parser_types_ts_1.GitFileStatus.Unmerged;
162
+ case ".":
163
+ return null;
164
+ default:
165
+ return null;
166
+ }
167
+ }
168
+ }
169
+ exports.GitParser = GitParser;
170
+ // build summary for parsed command
171
+ class GitSummaryBuilder {
172
+ static build(files) {
173
+ const summary = {
174
+ modified: 0,
175
+ added: 0,
176
+ deleted: 0,
177
+ renamed: 0,
178
+ copied: 0,
179
+ untracked: 0,
180
+ ignored: 0,
181
+ conflicted: 0,
182
+ staged: 0,
183
+ unstaged: 0,
184
+ total: files.length,
185
+ hasChanges: false,
186
+ hasStagedChanges: false,
187
+ hasUnstagedChanges: false,
188
+ hasUntrackedFiles: false,
189
+ hasConflicts: false,
190
+ isClean: true,
191
+ };
192
+ for (const file of files) {
193
+ this.countKind(summary, file);
194
+ this.countStatus(summary, file.indexStatus, true);
195
+ this.countStatus(summary, file.workTreeStatus, false);
196
+ }
197
+ // ------------------------------------------------------------------
198
+ // Derived values
199
+ // ------------------------------------------------------------------
200
+ summary.hasChanges = summary.total > 0;
201
+ summary.hasStagedChanges = summary.staged > 0;
202
+ summary.hasUnstagedChanges = summary.unstaged > 0;
203
+ summary.hasUntrackedFiles = summary.untracked > 0;
204
+ summary.hasConflicts = summary.conflicted > 0;
205
+ summary.isClean = !summary.hasChanges;
206
+ return summary;
207
+ }
208
+ static countKind(summary, file) {
209
+ switch (file.kind) {
210
+ case parser_types_ts_1.GitFileKind.Untracked:
211
+ summary.untracked++;
212
+ summary.unstaged++;
213
+ break;
214
+ case parser_types_ts_1.GitFileKind.Ignored:
215
+ summary.ignored++;
216
+ break;
217
+ case parser_types_ts_1.GitFileKind.Conflicted:
218
+ summary.conflicted++;
219
+ break;
220
+ }
221
+ }
222
+ static countStatus(summary, status, staged) {
223
+ if (!status) {
224
+ return;
225
+ }
226
+ if (staged) {
227
+ summary.staged++;
228
+ }
229
+ else {
230
+ summary.unstaged++;
231
+ }
232
+ switch (status) {
233
+ case parser_types_ts_1.GitFileStatus.Modified:
234
+ summary.modified++;
235
+ break;
236
+ case parser_types_ts_1.GitFileStatus.Added:
237
+ summary.added++;
238
+ break;
239
+ case parser_types_ts_1.GitFileStatus.Deleted:
240
+ summary.deleted++;
241
+ break;
242
+ case parser_types_ts_1.GitFileStatus.Renamed:
243
+ summary.renamed++;
244
+ break;
245
+ case parser_types_ts_1.GitFileStatus.Copied:
246
+ summary.copied++;
247
+ break;
248
+ case parser_types_ts_1.GitFileStatus.Unmerged:
249
+ summary.conflicted++;
250
+ break;
251
+ }
252
+ }
253
+ }
254
+ exports.GitSummaryBuilder = GitSummaryBuilder;
255
+ class GitDisplay {
256
+ static getFileIcon(file) {
257
+ if (file.kind === parser_types_ts_1.GitFileKind.Untracked) {
258
+ return "✨";
259
+ }
260
+ if (file.kind === parser_types_ts_1.GitFileKind.Ignored) {
261
+ return "🙈";
262
+ }
263
+ if (file.kind === parser_types_ts_1.GitFileKind.Rename) {
264
+ return "🔄";
265
+ }
266
+ if (file.kind === parser_types_ts_1.GitFileKind.Copy) {
267
+ return "📄";
268
+ }
269
+ if (file.kind === parser_types_ts_1.GitFileKind.Conflicted) {
270
+ return "⚠️";
271
+ }
272
+ const status = file.workTreeStatus ?? file.indexStatus;
273
+ switch (status) {
274
+ case parser_types_ts_1.GitFileStatus.Added:
275
+ return "➕";
276
+ case parser_types_ts_1.GitFileStatus.Modified:
277
+ return "📝";
278
+ case parser_types_ts_1.GitFileStatus.Deleted:
279
+ return "🗑";
280
+ case parser_types_ts_1.GitFileStatus.Renamed:
281
+ return "🔄";
282
+ case parser_types_ts_1.GitFileStatus.Copied:
283
+ return "📄";
284
+ case parser_types_ts_1.GitFileStatus.Unmerged:
285
+ return "⚠️";
286
+ default:
287
+ return "📄";
288
+ }
289
+ }
290
+ static getFileStatus(file) {
291
+ if (file.kind === parser_types_ts_1.GitFileKind.Untracked) {
292
+ return "Untracked";
293
+ }
294
+ if (file.kind === parser_types_ts_1.GitFileKind.Ignored) {
295
+ return "Ignored";
296
+ }
297
+ if (file.kind === parser_types_ts_1.GitFileKind.Conflicted) {
298
+ return "Conflicted";
299
+ }
300
+ return file.workTreeStatus ?? file.indexStatus ?? "Unknown";
301
+ }
302
+ static getFileLabel(file) {
303
+ const icon = this.getFileIcon(file);
304
+ if (file.kind === parser_types_ts_1.GitFileKind.Rename && file.originalPath) {
305
+ return `${icon} ${file.originalPath} → ${file.path}`;
306
+ }
307
+ return `${icon} ${file.path}`;
308
+ }
309
+ static getFileHint(file) {
310
+ const status = this.getFileStatus(file);
311
+ const parts = [status];
312
+ if (file.indexStatus) {
313
+ parts.push("Staged");
314
+ }
315
+ if (file.workTreeStatus) {
316
+ parts.push("Unstaged");
317
+ }
318
+ return parts.join(" • ");
319
+ }
320
+ static getBranchLabel(branch) {
321
+ let label = branch.current;
322
+ if (branch.detached) {
323
+ label = "Detached HEAD";
324
+ }
325
+ if (branch.upstream) {
326
+ label += ` (${branch.upstream})`;
327
+ }
328
+ return label;
329
+ }
330
+ static getBranchHint(branch) {
331
+ return `↑ ${branch.ahead} ↓ ${branch.behind}`;
332
+ }
333
+ static getFileSelectOptions(files) {
334
+ return [
335
+ {
336
+ label: "🌍 Stage all changes (.)",
337
+ value: ".",
338
+ hint: "Equivalent to: git add .",
339
+ },
340
+ ...files.map((file) => ({
341
+ label: this.getFileLabel(file),
342
+ value: file.path,
343
+ hint: this.getFileHint(file),
344
+ })),
345
+ ];
346
+ }
347
+ }
348
+ exports.GitDisplay = GitDisplay;
349
+ class GitStatusHelper {
350
+ static getStageableFiles(files) {
351
+ return files.filter((file) => {
352
+ if (file.kind === parser_types_ts_1.GitFileKind.Ignored) {
353
+ return false;
354
+ }
355
+ if (file.kind === parser_types_ts_1.GitFileKind.Untracked) {
356
+ return true;
357
+ }
358
+ // Has unstaged changes
359
+ if (file.workTreeStatus) {
360
+ return true;
361
+ }
362
+ // Already fully staged
363
+ return false;
364
+ });
365
+ }
366
+ }
367
+ exports.GitStatusHelper = GitStatusHelper;
368
+ //# sourceMappingURL=parser.services.js.map