github-archiver 1.0.2 → 1.0.5
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.
- package/.releaserc.json +9 -1
- package/CHANGELOG.md +25 -0
- package/dist/index.js +3 -3
- package/dist/index.js.map +2 -2
- package/package.json +6 -2
- package/.claude/CLAUDE.md +0 -248
- package/.claude/settings.json +0 -15
- package/.github/dependabot.yml +0 -76
- package/.github/workflows/ci.yml +0 -64
- package/.github/workflows/release.yml +0 -55
- package/AGENTS.md +0 -248
- package/CONTRIBUTING.md +0 -343
- package/QUICKSTART.md +0 -221
- package/bun.lock +0 -1380
- package/issues.txt +0 -1105
- package/notes.md +0 -0
- package/scripts/build.ts +0 -14
- package/src/commands/archive.ts +0 -344
- package/src/commands/auth.ts +0 -184
- package/src/constants/defaults.ts +0 -6
- package/src/constants/messages.ts +0 -24
- package/src/constants/paths.ts +0 -12
- package/src/index.ts +0 -42
- package/src/services/archiver.ts +0 -192
- package/src/services/auth-manager.ts +0 -79
- package/src/services/github.ts +0 -211
- package/src/types/config.ts +0 -24
- package/src/types/error.ts +0 -35
- package/src/types/github.ts +0 -34
- package/src/types/index.ts +0 -4
- package/src/utils/colors.ts +0 -79
- package/src/utils/config.ts +0 -95
- package/src/utils/errors.ts +0 -93
- package/src/utils/formatting.ts +0 -65
- package/src/utils/input-handler.ts +0 -163
- package/src/utils/logger.ts +0 -65
- package/src/utils/parser.ts +0 -125
- package/src/utils/progress.ts +0 -87
- package/tests/unit/formatting.test.ts +0 -93
- package/tests/unit/parser.test.ts +0 -140
- package/tsconfig.json +0 -36
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest";
|
|
2
|
-
import { Formatting } from "../../src/utils/formatting";
|
|
3
|
-
|
|
4
|
-
describe("Formatting", () => {
|
|
5
|
-
describe("formatDuration", () => {
|
|
6
|
-
it("should format milliseconds", () => {
|
|
7
|
-
expect(Formatting.formatDuration(500)).toBe("500ms");
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
it("should format seconds", () => {
|
|
11
|
-
expect(Formatting.formatDuration(1500)).toBe("1.5s");
|
|
12
|
-
expect(Formatting.formatDuration(5000)).toBe("5.0s");
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
it("should format minutes and seconds", () => {
|
|
16
|
-
expect(Formatting.formatDuration(65_000)).toContain("m");
|
|
17
|
-
expect(Formatting.formatDuration(120_000)).toBe("2m 0s");
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
it("should handle zero", () => {
|
|
21
|
-
expect(Formatting.formatDuration(0)).toBe("0ms");
|
|
22
|
-
});
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
describe("formatBytes", () => {
|
|
26
|
-
it("should format bytes", () => {
|
|
27
|
-
expect(Formatting.formatBytes(512)).toContain("B");
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
it("should format kilobytes", () => {
|
|
31
|
-
expect(Formatting.formatBytes(5120)).toContain("KB");
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
it("should handle zero bytes", () => {
|
|
35
|
-
expect(Formatting.formatBytes(0)).toBe("0 B");
|
|
36
|
-
});
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
describe("formatPercent", () => {
|
|
40
|
-
it("should format percentages", () => {
|
|
41
|
-
expect(Formatting.formatPercent(1, 2)).toBe("50.0%");
|
|
42
|
-
expect(Formatting.formatPercent(3, 4)).toBe("75.0%");
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
it("should handle zero total", () => {
|
|
46
|
-
expect(Formatting.formatPercent(0, 0)).toBe("0%");
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
it("should handle full percentage", () => {
|
|
50
|
-
expect(Formatting.formatPercent(100, 100)).toBe("100.0%");
|
|
51
|
-
});
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
describe("createProgressBar", () => {
|
|
55
|
-
it("should create a progress bar", () => {
|
|
56
|
-
const bar = Formatting.createProgressBar(50, 100, 10);
|
|
57
|
-
expect(bar).toContain("[");
|
|
58
|
-
expect(bar).toContain("]");
|
|
59
|
-
expect(bar).toContain("%");
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
it("should show 0% for zero progress", () => {
|
|
63
|
-
const bar = Formatting.createProgressBar(0, 100);
|
|
64
|
-
expect(bar).toContain("0%");
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
it("should show 100% for complete progress", () => {
|
|
68
|
-
const bar = Formatting.createProgressBar(100, 100);
|
|
69
|
-
expect(bar).toContain("100%");
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
it("should handle zero total", () => {
|
|
73
|
-
const bar = Formatting.createProgressBar(0, 0);
|
|
74
|
-
expect(bar).toBe("[ ]");
|
|
75
|
-
});
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
describe("truncate", () => {
|
|
79
|
-
it("should not truncate short strings", () => {
|
|
80
|
-
expect(Formatting.truncate("hello", 10)).toBe("hello");
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
it("should truncate long strings", () => {
|
|
84
|
-
const result = Formatting.truncate("hello world", 8);
|
|
85
|
-
expect(result.length).toBeLessThanOrEqual(8);
|
|
86
|
-
expect(result).toContain("...");
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
it("should handle exact length", () => {
|
|
90
|
-
expect(Formatting.truncate("hello", 5)).toBe("hello");
|
|
91
|
-
});
|
|
92
|
-
});
|
|
93
|
-
});
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest";
|
|
2
|
-
import { URLParser } from "../../src/utils/parser";
|
|
3
|
-
|
|
4
|
-
describe("URLParser", () => {
|
|
5
|
-
describe("parseRepositoryUrl", () => {
|
|
6
|
-
it("should parse HTTPS GitHub URLs", () => {
|
|
7
|
-
const result = URLParser.parseRepositoryUrl(
|
|
8
|
-
"https://github.com/owner/repo"
|
|
9
|
-
);
|
|
10
|
-
expect(result.owner).toBe("owner");
|
|
11
|
-
expect(result.repo).toBe("repo");
|
|
12
|
-
expect(result.url).toBe("https://github.com/owner/repo");
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
it("should parse HTTPS URLs with .git suffix", () => {
|
|
16
|
-
const result = URLParser.parseRepositoryUrl(
|
|
17
|
-
"https://github.com/owner/repo.git"
|
|
18
|
-
);
|
|
19
|
-
expect(result.owner).toBe("owner");
|
|
20
|
-
expect(result.repo).toBe("repo");
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
it("should parse SSH URLs", () => {
|
|
24
|
-
const result = URLParser.parseRepositoryUrl(
|
|
25
|
-
"git@github.com:owner/repo.git"
|
|
26
|
-
);
|
|
27
|
-
expect(result.owner).toBe("owner");
|
|
28
|
-
expect(result.repo).toBe("repo");
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
it("should parse shorthand owner/repo format", () => {
|
|
32
|
-
const result = URLParser.parseRepositoryUrl("owner/repo");
|
|
33
|
-
expect(result.owner).toBe("owner");
|
|
34
|
-
expect(result.repo).toBe("repo");
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
it("should parse URLs with special characters in names", () => {
|
|
38
|
-
const result = URLParser.parseRepositoryUrl("my-org/my-repo-123");
|
|
39
|
-
expect(result.owner).toBe("my-org");
|
|
40
|
-
expect(result.repo).toBe("my-repo-123");
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
it("should handle case-insensitive domains", () => {
|
|
44
|
-
const result = URLParser.parseRepositoryUrl(
|
|
45
|
-
"HTTPS://GITHUB.COM/owner/repo"
|
|
46
|
-
);
|
|
47
|
-
expect(result.owner).toBe("owner");
|
|
48
|
-
expect(result.repo).toBe("repo");
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
it("should throw error for empty URL", () => {
|
|
52
|
-
expect(() => URLParser.parseRepositoryUrl("")).toThrow();
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it("should throw error for malformed URLs", () => {
|
|
56
|
-
expect(() => URLParser.parseRepositoryUrl("invalid-url")).toThrow();
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
it("should throw error for missing repo name", () => {
|
|
60
|
-
expect(() =>
|
|
61
|
-
URLParser.parseRepositoryUrl("https://github.com/owner/")
|
|
62
|
-
).toThrow();
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
it("should normalize URLs to HTTPS format", () => {
|
|
66
|
-
const http = URLParser.parseRepositoryUrl("http://github.com/owner/repo");
|
|
67
|
-
const ssh = URLParser.parseRepositoryUrl("git@github.com:owner/repo.git");
|
|
68
|
-
const short = URLParser.parseRepositoryUrl("owner/repo");
|
|
69
|
-
|
|
70
|
-
expect(http.url).toBe("https://github.com/owner/repo");
|
|
71
|
-
expect(ssh.url).toBe("https://github.com/owner/repo");
|
|
72
|
-
expect(short.url).toBe("https://github.com/owner/repo");
|
|
73
|
-
});
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
describe("parseRepositoriesBatch", () => {
|
|
77
|
-
it("should parse multiple valid URLs", () => {
|
|
78
|
-
const urls = [
|
|
79
|
-
"https://github.com/owner1/repo1",
|
|
80
|
-
"git@github.com:owner2/repo2.git",
|
|
81
|
-
"owner3/repo3",
|
|
82
|
-
];
|
|
83
|
-
const result = URLParser.parseRepositoriesBatch(urls);
|
|
84
|
-
|
|
85
|
-
expect(result.valid).toHaveLength(3);
|
|
86
|
-
expect(result.invalid).toHaveLength(0);
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
it("should skip empty lines", () => {
|
|
90
|
-
const urls = ["owner/repo1", "", "owner/repo2", " "];
|
|
91
|
-
const result = URLParser.parseRepositoriesBatch(urls);
|
|
92
|
-
|
|
93
|
-
expect(result.valid).toHaveLength(2);
|
|
94
|
-
expect(result.invalid).toHaveLength(0);
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
it("should skip comment lines", () => {
|
|
98
|
-
const urls = [
|
|
99
|
-
"# This is a comment",
|
|
100
|
-
"owner/repo1",
|
|
101
|
-
"# Another comment",
|
|
102
|
-
"owner/repo2",
|
|
103
|
-
];
|
|
104
|
-
const result = URLParser.parseRepositoriesBatch(urls);
|
|
105
|
-
|
|
106
|
-
expect(result.valid).toHaveLength(2);
|
|
107
|
-
expect(result.invalid).toHaveLength(0);
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
it("should handle mixed valid and invalid URLs", () => {
|
|
111
|
-
const urls = ["owner/repo1", "invalid", "owner/repo2", "also-invalid"];
|
|
112
|
-
const result = URLParser.parseRepositoriesBatch(urls);
|
|
113
|
-
|
|
114
|
-
expect(result.valid).toHaveLength(2);
|
|
115
|
-
expect(result.invalid).toHaveLength(2);
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
it("should include line numbers in errors", () => {
|
|
119
|
-
const urls = ["owner/repo1", "invalid", "owner/repo2"];
|
|
120
|
-
const result = URLParser.parseRepositoriesBatch(urls);
|
|
121
|
-
|
|
122
|
-
expect(result.invalid[0].line).toBe(2);
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
it("should handle empty batch", () => {
|
|
126
|
-
const result = URLParser.parseRepositoriesBatch([]);
|
|
127
|
-
|
|
128
|
-
expect(result.valid).toHaveLength(0);
|
|
129
|
-
expect(result.invalid).toHaveLength(0);
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
it("should handle batch with only comments and whitespace", () => {
|
|
133
|
-
const urls = ["# Comment", "", " "];
|
|
134
|
-
const result = URLParser.parseRepositoriesBatch(urls);
|
|
135
|
-
|
|
136
|
-
expect(result.valid).toHaveLength(0);
|
|
137
|
-
expect(result.invalid).toHaveLength(0);
|
|
138
|
-
});
|
|
139
|
-
});
|
|
140
|
-
});
|
package/tsconfig.json
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2020",
|
|
4
|
-
"module": "ESNext",
|
|
5
|
-
"lib": ["ES2020"],
|
|
6
|
-
"moduleResolution": "bundler",
|
|
7
|
-
"outDir": "./dist",
|
|
8
|
-
"rootDir": "./src",
|
|
9
|
-
"strict": true,
|
|
10
|
-
"noImplicitAny": true,
|
|
11
|
-
"strictNullChecks": true,
|
|
12
|
-
"strictFunctionTypes": true,
|
|
13
|
-
"strictBindCallApply": true,
|
|
14
|
-
"strictPropertyInitialization": true,
|
|
15
|
-
"noImplicitThis": true,
|
|
16
|
-
"alwaysStrict": true,
|
|
17
|
-
"noUnusedLocals": true,
|
|
18
|
-
"noUnusedParameters": true,
|
|
19
|
-
"noImplicitReturns": true,
|
|
20
|
-
"noFallthroughCasesInSwitch": true,
|
|
21
|
-
"noUncheckedIndexedAccess": true,
|
|
22
|
-
"noImplicitOverride": true,
|
|
23
|
-
"allowUnusedLabels": false,
|
|
24
|
-
"allowUnreachableCode": false,
|
|
25
|
-
"esModuleInterop": true,
|
|
26
|
-
"skipLibCheck": true,
|
|
27
|
-
"forceConsistentCasingInFileNames": true,
|
|
28
|
-
"resolveJsonModule": true,
|
|
29
|
-
"declaration": true,
|
|
30
|
-
"declarationMap": true,
|
|
31
|
-
"sourceMap": true,
|
|
32
|
-
"types": ["node"]
|
|
33
|
-
},
|
|
34
|
-
"include": ["src/**/*.ts"],
|
|
35
|
-
"exclude": ["node_modules", "dist", "tests"]
|
|
36
|
-
}
|