@hallaxius/forge 0.1.3 → 0.1.4

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.md +160 -158
  2. package/bin/forge.js +2 -2
  3. package/dist/cli.js +12764 -13800
  4. package/package.json +75 -75
  5. package/src/cli.ts +80 -78
  6. package/src/commands/account.ts +80 -0
  7. package/src/commands/alias.ts +66 -66
  8. package/src/commands/branch.ts +46 -46
  9. package/src/commands/ci.ts +28 -28
  10. package/src/commands/clone.ts +100 -100
  11. package/src/commands/commit.ts +88 -88
  12. package/src/commands/config.ts +47 -48
  13. package/src/commands/diff.ts +26 -26
  14. package/src/commands/fetch.ts +20 -20
  15. package/src/commands/help.ts +58 -58
  16. package/src/commands/init.ts +32 -33
  17. package/src/commands/issue.ts +63 -63
  18. package/src/commands/log.ts +29 -29
  19. package/src/commands/merge.ts +37 -37
  20. package/src/commands/pr.ts +65 -65
  21. package/src/commands/push.ts +35 -35
  22. package/src/commands/release.ts +26 -26
  23. package/src/commands/remote.ts +107 -107
  24. package/src/commands/reset.ts +30 -30
  25. package/src/commands/setup.ts +93 -94
  26. package/src/commands/stash.ts +44 -44
  27. package/src/commands/status.ts +74 -74
  28. package/src/commands/sync.ts +20 -20
  29. package/src/commands/tag.ts +41 -41
  30. package/src/commands/undo.ts +27 -27
  31. package/src/commands/version.ts +12 -12
  32. package/src/constants/colors.ts +7 -7
  33. package/src/constants/commit-types.ts +24 -24
  34. package/src/constants/messages.ts +13 -23
  35. package/src/lib/auth.ts +172 -172
  36. package/src/lib/config.ts +108 -108
  37. package/src/lib/git.ts +543 -543
  38. package/src/lib/github.ts +202 -160
  39. package/src/lib/logger.ts +18 -31
  40. package/src/lib/ui.ts +122 -156
  41. package/src/lib/validators.ts +16 -16
  42. package/src/templates/commit-types.json +9 -9
  43. package/src/utils/files.ts +21 -21
  44. package/src/utils/strings.ts +19 -19
  45. package/src/version.const.ts +1 -1
package/src/lib/github.ts CHANGED
@@ -1,160 +1,202 @@
1
- import fs from "node:fs";
2
- import { Octokit } from "@octokit/rest";
3
- import { currentBranch, getConfig } from "isomorphic-git";
4
- import { resolveToken } from "./auth.js";
5
-
6
- function parseRemoteUrl(remoteUrl: string): { owner: string; repo: string } {
7
- const match = remoteUrl.match(
8
- /github\.com[:/]([\w.-]+)\/([\w.-]+?)(?:\.git)?$/,
9
- );
10
- if (!match)
11
- throw new Error(
12
- `Could not determine GitHub repo from remote URL: ${remoteUrl}`,
13
- );
14
- return { owner: match[1], repo: match[2] };
15
- }
16
-
17
- async function createClient(): Promise<Octokit> {
18
- const token = await resolveToken();
19
- return new Octokit({ auth: token });
20
- }
21
-
22
- export async function getRepoInfo(): Promise<{ owner: string; repo: string }> {
23
- const dir = process.cwd();
24
- const remoteUrl = await getConfig({ fs, dir, path: "remote.origin.url" });
25
- if (!remoteUrl)
26
- throw new Error(
27
- "No remote 'origin' configured. Set up a GitHub remote first.",
28
- );
29
- return parseRemoteUrl(remoteUrl);
30
- }
31
-
32
- export async function createPR(
33
- title: string,
34
- body: string,
35
- head: string,
36
- base: string = "main",
37
- ): Promise<{ number: number; url: string }> {
38
- const octokit = await createClient();
39
- const { owner, repo } = await getRepoInfo();
40
- const { data } = await octokit.pulls.create({
41
- owner,
42
- repo,
43
- title,
44
- body,
45
- head,
46
- base,
47
- });
48
- return { number: data.number, url: data.html_url };
49
- }
50
-
51
- export async function listPRs(
52
- state: "open" | "closed" | "all" = "open",
53
- ): Promise<
54
- {
55
- number: number;
56
- title: string;
57
- state: string;
58
- url: string;
59
- author: string;
60
- }[]
61
- > {
62
- const octokit = await createClient();
63
- const { owner, repo } = await getRepoInfo();
64
- const { data } = await octokit.pulls.list({
65
- owner,
66
- repo,
67
- state,
68
- per_page: 20,
69
- });
70
- return data.map((pr) => ({
71
- number: pr.number,
72
- title: pr.title,
73
- state: pr.state,
74
- url: pr.html_url,
75
- author: pr.user?.login || "",
76
- }));
77
- }
78
-
79
- export async function createIssue(
80
- title: string,
81
- body: string,
82
- labels: string[] = [],
83
- ): Promise<{ number: number; url: string }> {
84
- const octokit = await createClient();
85
- const { owner, repo } = await getRepoInfo();
86
- const { data } = await octokit.issues.create({
87
- owner,
88
- repo,
89
- title,
90
- body,
91
- labels,
92
- });
93
- return { number: data.number, url: data.html_url };
94
- }
95
-
96
- export async function listIssues(
97
- state: "open" | "closed" | "all" = "open",
98
- ): Promise<
99
- {
100
- number: number;
101
- title: string;
102
- state: string;
103
- url: string;
104
- author: string;
105
- }[]
106
- > {
107
- const octokit = await createClient();
108
- const { owner, repo } = await getRepoInfo();
109
- const { data } = await octokit.issues.list({
110
- owner,
111
- repo,
112
- state,
113
- per_page: 20,
114
- });
115
- return data.map((issue) => ({
116
- number: issue.number,
117
- title: issue.title,
118
- state: issue.state,
119
- url: issue.html_url,
120
- author: issue.user?.login || "",
121
- }));
122
- }
123
-
124
- export async function createRelease(
125
- tag: string,
126
- name: string,
127
- body: string,
128
- ): Promise<{ url: string }> {
129
- const octokit = await createClient();
130
- const { owner, repo } = await getRepoInfo();
131
- const { data } = await octokit.repos.createRelease({
132
- owner,
133
- repo,
134
- tag_name: tag,
135
- name,
136
- body,
137
- });
138
- return { url: data.html_url };
139
- }
140
-
141
- export async function getCIStatus(): Promise<
142
- { branch: string; name: string; conclusion: string; url: string }[]
143
- > {
144
- const octokit = await createClient();
145
- const { owner, repo } = await getRepoInfo();
146
- const dir = process.cwd();
147
- const branch = (await currentBranch({ fs, dir })) || "HEAD";
148
- const { data } = await octokit.checks.listForRef({
149
- owner,
150
- repo,
151
- ref: branch,
152
- per_page: 10,
153
- });
154
- return data.check_runs.map((run) => ({
155
- branch,
156
- name: run.name,
157
- conclusion: run.conclusion || "pending",
158
- url: run.html_url,
159
- }));
160
- }
1
+ import fs from "node:fs";
2
+ import { Octokit } from "@octokit/rest";
3
+ import { currentBranch, getConfig } from "isomorphic-git";
4
+ import { resolveToken } from "./auth.js";
5
+
6
+ function parseRemoteUrl(remoteUrl: string): { owner: string; repo: string } {
7
+ const match = remoteUrl.match(
8
+ /github\.com[:/]([\w.-]+)\/([\w.-]+?)(?:\.git)?$/,
9
+ );
10
+ if (!match)
11
+ throw new Error(
12
+ `Could not determine GitHub repo from remote URL: ${remoteUrl}`,
13
+ );
14
+ return { owner: match[1], repo: match[2] };
15
+ }
16
+
17
+ async function createClient(): Promise<Octokit> {
18
+ const token = await resolveToken();
19
+ return new Octokit({ auth: token });
20
+ }
21
+
22
+ export async function getRepoInfo(): Promise<{ owner: string; repo: string }> {
23
+ const dir = process.cwd();
24
+ const remoteUrl = await getConfig({ fs, dir, path: "remote.origin.url" });
25
+ if (!remoteUrl)
26
+ throw new Error(
27
+ "No remote 'origin' configured. Set up a GitHub remote first.",
28
+ );
29
+ return parseRemoteUrl(remoteUrl);
30
+ }
31
+
32
+ export async function createPR(
33
+ title: string,
34
+ body: string,
35
+ head: string,
36
+ base: string = "main",
37
+ ): Promise<{ number: number; url: string }> {
38
+ const octokit = await createClient();
39
+ const { owner, repo } = await getRepoInfo();
40
+ const { data } = await octokit.pulls.create({
41
+ owner,
42
+ repo,
43
+ title,
44
+ body,
45
+ head,
46
+ base,
47
+ });
48
+ return { number: data.number, url: data.html_url };
49
+ }
50
+
51
+ export async function listPRs(
52
+ state: "open" | "closed" | "all" = "open",
53
+ ): Promise<
54
+ {
55
+ number: number;
56
+ title: string;
57
+ state: string;
58
+ url: string;
59
+ author: string;
60
+ }[]
61
+ > {
62
+ const octokit = await createClient();
63
+ const { owner, repo } = await getRepoInfo();
64
+ const { data } = await octokit.pulls.list({
65
+ owner,
66
+ repo,
67
+ state,
68
+ per_page: 20,
69
+ });
70
+ return data.map((pr) => ({
71
+ number: pr.number,
72
+ title: pr.title,
73
+ state: pr.state,
74
+ url: pr.html_url,
75
+ author: pr.user?.login || "",
76
+ }));
77
+ }
78
+
79
+ export async function createIssue(
80
+ title: string,
81
+ body: string,
82
+ labels: string[] = [],
83
+ ): Promise<{ number: number; url: string }> {
84
+ const octokit = await createClient();
85
+ const { owner, repo } = await getRepoInfo();
86
+ const { data } = await octokit.issues.create({
87
+ owner,
88
+ repo,
89
+ title,
90
+ body,
91
+ labels,
92
+ });
93
+ return { number: data.number, url: data.html_url };
94
+ }
95
+
96
+ export async function listIssues(
97
+ state: "open" | "closed" | "all" = "open",
98
+ ): Promise<
99
+ {
100
+ number: number;
101
+ title: string;
102
+ state: string;
103
+ url: string;
104
+ author: string;
105
+ }[]
106
+ > {
107
+ const octokit = await createClient();
108
+ const { owner, repo } = await getRepoInfo();
109
+ const { data } = await octokit.issues.list({
110
+ owner,
111
+ repo,
112
+ state,
113
+ per_page: 20,
114
+ });
115
+ return data.map((issue) => ({
116
+ number: issue.number,
117
+ title: issue.title,
118
+ state: issue.state,
119
+ url: issue.html_url,
120
+ author: issue.user?.login || "",
121
+ }));
122
+ }
123
+
124
+ export async function createRelease(
125
+ tag: string,
126
+ name: string,
127
+ body: string,
128
+ ): Promise<{ url: string }> {
129
+ const octokit = await createClient();
130
+ const { owner, repo } = await getRepoInfo();
131
+ const { data } = await octokit.repos.createRelease({
132
+ owner,
133
+ repo,
134
+ tag_name: tag,
135
+ name,
136
+ body,
137
+ });
138
+ return { url: data.html_url };
139
+ }
140
+
141
+ export interface AccountInfo {
142
+ login: string;
143
+ name: string | null;
144
+ email: string | null;
145
+ avatarUrl: string;
146
+ profileUrl: string;
147
+ publicRepos: number;
148
+ publicGists: number;
149
+ followers: number;
150
+ following: number;
151
+ createdAt: string;
152
+ plan: string | null;
153
+ bio: string | null;
154
+ company: string | null;
155
+ location: string | null;
156
+ twitter: string | null;
157
+ blog: string | null;
158
+ }
159
+
160
+ export async function getAccountInfo(): Promise<AccountInfo> {
161
+ const octokit = await createClient();
162
+ const { data } = await octokit.users.getAuthenticated();
163
+ return {
164
+ login: data.login,
165
+ name: data.name ?? null,
166
+ email: data.email ?? null,
167
+ avatarUrl: data.avatar_url,
168
+ profileUrl: data.html_url,
169
+ publicRepos: data.public_repos,
170
+ publicGists: data.public_gists,
171
+ followers: data.followers,
172
+ following: data.following,
173
+ createdAt: data.created_at,
174
+ plan: data.plan?.name ?? null,
175
+ bio: data.bio ?? null,
176
+ company: data.company ?? null,
177
+ location: data.location ?? null,
178
+ twitter: data.twitter_username ?? null,
179
+ blog: data.blog ?? null,
180
+ };
181
+ }
182
+
183
+ export async function getCIStatus(): Promise<
184
+ { branch: string; name: string; conclusion: string; url: string }[]
185
+ > {
186
+ const octokit = await createClient();
187
+ const { owner, repo } = await getRepoInfo();
188
+ const dir = process.cwd();
189
+ const branch = (await currentBranch({ fs, dir })) || "HEAD";
190
+ const { data } = await octokit.checks.listForRef({
191
+ owner,
192
+ repo,
193
+ ref: branch,
194
+ per_page: 10,
195
+ });
196
+ return data.check_runs.map((run) => ({
197
+ branch,
198
+ name: run.name,
199
+ conclusion: run.conclusion || "pending",
200
+ url: run.html_url,
201
+ }));
202
+ }
package/src/lib/logger.ts CHANGED
@@ -1,31 +1,18 @@
1
- import chalk from "chalk";
2
- import { colors } from "../constants/colors.js";
3
- import { icons } from "../constants/messages.js";
4
-
5
- export function success(msg: string): void {
6
- console.log(chalk.hex(colors.success)(`${icons.success} ${msg}`));
7
- }
8
-
9
- export function error(msg: string): void {
10
- console.error(chalk.hex(colors.error)(`${icons.error} ${msg}`));
11
- }
12
-
13
- export function warning(msg: string): void {
14
- console.warn(chalk.hex(colors.warning)(`${icons.warning} ${msg}`));
15
- }
16
-
17
- export function info(msg: string): void {
18
- console.log(chalk.hex(colors.info)(`${icons.info} ${msg}`));
19
- }
20
-
21
- export function highlight(msg: string): void {
22
- console.log(chalk.hex(colors.highlight)(`${icons.highlight} ${msg}`));
23
- }
24
-
25
- export function text(msg: string): void {
26
- console.log(msg);
27
- }
28
-
29
- export function newline(): void {
30
- console.log();
31
- }
1
+ import chalk from "chalk";
2
+ import { colors } from "../constants/colors.js";
3
+
4
+ export function error(msg: string): void {
5
+ console.error(chalk.hex(colors.error)(msg));
6
+ }
7
+
8
+ export function warning(msg: string): void {
9
+ console.warn(chalk.hex(colors.warning)(`warning: ${msg}`));
10
+ }
11
+
12
+ export function text(msg: string): void {
13
+ console.log(msg);
14
+ }
15
+
16
+ export function newline(): void {
17
+ console.log();
18
+ }