@dependabit/github-client 0.1.1

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 (70) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/LICENSE +21 -0
  3. package/README.md +266 -0
  4. package/dist/auth/basic.d.ts +46 -0
  5. package/dist/auth/basic.d.ts.map +1 -0
  6. package/dist/auth/basic.js +88 -0
  7. package/dist/auth/basic.js.map +1 -0
  8. package/dist/auth/oauth.d.ts +48 -0
  9. package/dist/auth/oauth.d.ts.map +1 -0
  10. package/dist/auth/oauth.js +139 -0
  11. package/dist/auth/oauth.js.map +1 -0
  12. package/dist/auth/token.d.ts +40 -0
  13. package/dist/auth/token.d.ts.map +1 -0
  14. package/dist/auth/token.js +67 -0
  15. package/dist/auth/token.js.map +1 -0
  16. package/dist/auth.d.ts +47 -0
  17. package/dist/auth.d.ts.map +1 -0
  18. package/dist/auth.js +78 -0
  19. package/dist/auth.js.map +1 -0
  20. package/dist/client.d.ts +53 -0
  21. package/dist/client.d.ts.map +1 -0
  22. package/dist/client.js +74 -0
  23. package/dist/client.js.map +1 -0
  24. package/dist/commits.d.ts +57 -0
  25. package/dist/commits.d.ts.map +1 -0
  26. package/dist/commits.js +113 -0
  27. package/dist/commits.js.map +1 -0
  28. package/dist/feedback.d.ts +69 -0
  29. package/dist/feedback.d.ts.map +1 -0
  30. package/dist/feedback.js +111 -0
  31. package/dist/feedback.js.map +1 -0
  32. package/dist/index.d.ts +15 -0
  33. package/dist/index.d.ts.map +1 -0
  34. package/dist/index.js +11 -0
  35. package/dist/index.js.map +1 -0
  36. package/dist/issues.d.ts +55 -0
  37. package/dist/issues.d.ts.map +1 -0
  38. package/dist/issues.js +123 -0
  39. package/dist/issues.js.map +1 -0
  40. package/dist/rate-limit.d.ts +71 -0
  41. package/dist/rate-limit.d.ts.map +1 -0
  42. package/dist/rate-limit.js +145 -0
  43. package/dist/rate-limit.js.map +1 -0
  44. package/dist/releases.d.ts +50 -0
  45. package/dist/releases.d.ts.map +1 -0
  46. package/dist/releases.js +113 -0
  47. package/dist/releases.js.map +1 -0
  48. package/package.json +39 -0
  49. package/src/auth/basic.ts +102 -0
  50. package/src/auth/oauth.ts +183 -0
  51. package/src/auth/token.ts +81 -0
  52. package/src/auth.ts +100 -0
  53. package/src/client.test.ts +115 -0
  54. package/src/client.ts +109 -0
  55. package/src/commits.ts +184 -0
  56. package/src/feedback.ts +166 -0
  57. package/src/index.ts +15 -0
  58. package/src/issues.ts +185 -0
  59. package/src/rate-limit.ts +210 -0
  60. package/src/releases.ts +149 -0
  61. package/test/auth/basic.test.ts +122 -0
  62. package/test/auth/oauth.test.ts +196 -0
  63. package/test/auth/token.test.ts +97 -0
  64. package/test/commits.test.ts +169 -0
  65. package/test/feedback.test.ts +203 -0
  66. package/test/issues.test.ts +197 -0
  67. package/test/rate-limit.test.ts +154 -0
  68. package/test/releases.test.ts +187 -0
  69. package/tsconfig.json +10 -0
  70. package/tsconfig.tsbuildinfo +1 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,7 @@
1
+ # @dependabit/github-client
2
+
3
+ ## 0.1.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Publish release setup updates and action metadata.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024-present Pradeep Mouli
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,266 @@
1
+ # @dependabit/github-client
2
+
3
+ Comprehensive GitHub API wrapper with authentication, rate limiting, and false positive tracking.
4
+
5
+ ## Overview
6
+
7
+ This package provides a robust wrapper around the GitHub API with built-in rate limiting, multiple authentication strategies, and specialized features for dependency tracking workflows.
8
+
9
+ ## Features
10
+
11
+ - **Rate Limiting**: Automatic rate limit handling with budget reservation
12
+ - **Authentication**: Token, OAuth, and Basic auth support
13
+ - **Issue Management**: Create, update, and track dependency issues
14
+ - **Release Monitoring**: Fetch and compare releases
15
+ - **Commit Tracking**: Retrieve commit history and changes
16
+ - **Feedback Collection**: Monitor false positive feedback via issue labels
17
+ - **Proactive Quota Management**: Reserve API calls before execution
18
+
19
+ ## Installation
20
+
21
+ ```bash
22
+ pnpm add @dependabit/github-client
23
+ ```
24
+
25
+ ## Usage
26
+
27
+ ### Basic Client
28
+
29
+ ```typescript
30
+ import { createGitHubClient } from '@dependabit/github-client';
31
+
32
+ const client = createGitHubClient({
33
+ auth: process.env.GITHUB_TOKEN,
34
+ rateLimitWarningThreshold: 100,
35
+ rateLimitMinRemaining: 10
36
+ });
37
+
38
+ // Use with rate limit checking
39
+ await client.withRateLimit(async () => {
40
+ // Your API calls here
41
+ });
42
+ ```
43
+
44
+ ### Authentication
45
+
46
+ #### Token Authentication
47
+ ```typescript
48
+ import { TokenAuthHandler } from '@dependabit/github-client';
49
+
50
+ const tokenAuth = new TokenAuthHandler('ghp_yourtoken');
51
+ const auth = await tokenAuth.authenticate();
52
+ // { type: 'token', token: 'ghp_yourtoken' }
53
+ ```
54
+
55
+ #### OAuth Authentication
56
+ ```typescript
57
+ import { OAuthHandler } from '@dependabit/github-client';
58
+
59
+ const oauth = new OAuthHandler({
60
+ clientId: 'your_client_id',
61
+ clientSecret: 'your_secret',
62
+ redirectUri: 'http://localhost:3000/callback'
63
+ });
64
+
65
+ // Get authorization URL
66
+ const authUrl = oauth.getAuthorizationUrl(['repo', 'user']);
67
+
68
+ // Exchange code for token
69
+ const auth = await oauth.authenticate(authorizationCode);
70
+ ```
71
+
72
+ #### Basic Authentication
73
+ ```typescript
74
+ import { BasicAuthHandler } from '@dependabit/github-client';
75
+
76
+ const basicAuth = new BasicAuthHandler('username', 'password');
77
+ const auth = await basicAuth.authenticate();
78
+ ```
79
+
80
+ ### Rate Limit Management
81
+
82
+ ```typescript
83
+ import { RateLimitHandler } from '@dependabit/github-client';
84
+
85
+ const rateLimit = new RateLimitHandler(token);
86
+
87
+ // Check current rate limit
88
+ const info = await rateLimit.checkRateLimit();
89
+ console.log(`${info.remaining}/${info.limit} requests remaining`);
90
+
91
+ // Reserve budget before operations
92
+ const reservation = await rateLimit.reserveBudget(50, {
93
+ safetyMargin: 10,
94
+ maxWaitTime: 60000
95
+ });
96
+
97
+ if (!reservation.reserved) {
98
+ console.log(`Cannot proceed: ${reservation.reason}`);
99
+ }
100
+
101
+ // Proactive checking
102
+ const canProceed = await rateLimit.canProceed(100, {
103
+ threshold: 50,
104
+ safetyMargin: 20
105
+ });
106
+ ```
107
+
108
+ ### Issue Management
109
+
110
+ ```typescript
111
+ import { IssueManager } from '@dependabit/github-client';
112
+
113
+ const issues = new IssueManager(token);
114
+
115
+ // Create issue for dependency update
116
+ const issue = await issues.createIssue({
117
+ owner: 'user',
118
+ repo: 'project',
119
+ title: 'Update dependency X',
120
+ body: 'New version available',
121
+ severity: 'minor',
122
+ dependency: {
123
+ id: 'dep-123',
124
+ url: 'https://github.com/org/dep'
125
+ }
126
+ });
127
+
128
+ // Find existing issue
129
+ const existing = await issues.findExistingIssue({
130
+ owner: 'user',
131
+ repo: 'project',
132
+ dependencyId: 'dep-123'
133
+ });
134
+
135
+ // Update issue
136
+ await issues.updateIssue({
137
+ owner: 'user',
138
+ repo: 'project',
139
+ issueNumber: 42,
140
+ body: 'Updated information',
141
+ severity: 'major'
142
+ });
143
+ ```
144
+
145
+ ### Release Management
146
+
147
+ ```typescript
148
+ import { ReleaseManager } from '@dependabit/github-client';
149
+
150
+ const releases = new ReleaseManager(token);
151
+
152
+ // Get latest release
153
+ const latest = await releases.getLatestRelease('owner', 'repo');
154
+
155
+ // Get specific release
156
+ const release = await releases.getReleaseByTag('owner', 'repo', 'v1.0.0');
157
+
158
+ // Compare releases
159
+ const comparison = await releases.compareReleases(
160
+ 'owner',
161
+ 'repo',
162
+ 'v1.0.0',
163
+ 'v2.0.0'
164
+ );
165
+
166
+ console.log(`Breaking changes: ${comparison.hasBreakingChanges}`);
167
+ ```
168
+
169
+ ### Commit Tracking
170
+
171
+ ```typescript
172
+ import { getCommitsSince } from '@dependabit/github-client';
173
+
174
+ const commits = await getCommitsSince({
175
+ owner: 'user',
176
+ repo: 'project',
177
+ since: new Date('2024-01-01'),
178
+ author: 'username'
179
+ });
180
+ ```
181
+
182
+ ### False Positive Feedback
183
+
184
+ ```typescript
185
+ import { FeedbackListener } from '@dependabit/github-client';
186
+
187
+ const feedback = new FeedbackListener(issueManager, {
188
+ truePositiveLabel: 'true-positive',
189
+ falsePositiveLabel: 'false-positive'
190
+ });
191
+
192
+ // Collect feedback from last 30 days
193
+ const data = await feedback.getRecentFeedback(30);
194
+
195
+ console.log(`False positives: ${data.falsePositives.length}`);
196
+ console.log(`True positives: ${data.truePositives.length}`);
197
+
198
+ // Calculate rate
199
+ const rate = await feedback.getFeedbackRate();
200
+ console.log(`FP rate: ${(rate.falsePositiveRate * 100).toFixed(1)}%`);
201
+
202
+ // Monitor specific issue
203
+ const hasFeedback = await feedback.monitorIssue(123);
204
+ ```
205
+
206
+ ## API Reference
207
+
208
+ ### Client
209
+
210
+ - `createGitHubClient(config)`: Create client instance
211
+ - `getRateLimit()`: Get current rate limit info
212
+ - `checkRateLimit()`: Check and warn about rate limits
213
+ - `withRateLimit(fn)`: Execute function with rate limit checking
214
+
215
+ ### Authentication
216
+
217
+ - `TokenAuthHandler`: GitHub PAT authentication
218
+ - `OAuthHandler`: OAuth 2.0 flow
219
+ - `BasicAuthHandler`: Basic HTTP authentication
220
+ - `AuthManager`: Unified auth management
221
+
222
+ ### Rate Limiting
223
+
224
+ - `RateLimitHandler`: Rate limit management
225
+ - `reserveBudget(calls, options)`: Reserve API call budget
226
+ - `canProceed(calls, options)`: Check if operation can proceed
227
+ - `getRateLimitStatus()`: Get detailed status
228
+
229
+ ### Issues
230
+
231
+ - `createIssue(data)`: Create new issue
232
+ - `findExistingIssue(params)`: Find existing issue
233
+ - `updateIssue(data)`: Update issue
234
+
235
+ ### Releases
236
+
237
+ - `getLatestRelease(owner, repo)`: Get latest release
238
+ - `getReleaseByTag(owner, repo, tag)`: Get specific release
239
+ - `compareReleases(owner, repo, from, to)`: Compare two releases
240
+
241
+ ### Feedback
242
+
243
+ - `FeedbackListener`: Monitor false positive feedback
244
+ - `collectFeedback(options)`: Collect feedback data
245
+ - `getFeedbackRate(options)`: Calculate FP rate
246
+ - `getRecentFeedback(days)`: Get recent feedback
247
+
248
+ ## Development
249
+
250
+ ```bash
251
+ # Install dependencies
252
+ pnpm install
253
+
254
+ # Build
255
+ pnpm build
256
+
257
+ # Run tests
258
+ pnpm test
259
+
260
+ # Type check
261
+ pnpm type-check
262
+ ```
263
+
264
+ ## License
265
+
266
+ MIT
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Basic authentication handler for GitHub API
3
+ * Supports username/password or username/personal access token
4
+ */
5
+ export interface BasicAuth {
6
+ type: 'basic';
7
+ username: string;
8
+ password: string;
9
+ }
10
+ /**
11
+ * Handler for HTTP Basic authentication
12
+ */
13
+ export declare class BasicAuthHandler {
14
+ private username;
15
+ private password;
16
+ constructor(username: string, password: string);
17
+ /**
18
+ * Authenticate and return auth object
19
+ */
20
+ authenticate(): Promise<BasicAuth>;
21
+ /**
22
+ * Get base64-encoded Basic auth header value
23
+ */
24
+ getAuthHeader(): string;
25
+ /**
26
+ * Validate credentials format
27
+ */
28
+ validate(): boolean;
29
+ /**
30
+ * Get authentication type
31
+ */
32
+ getType(): string;
33
+ /**
34
+ * Update credentials (for rotation)
35
+ */
36
+ updateCredentials(username: string, password: string): void;
37
+ /**
38
+ * String representation (masks password)
39
+ */
40
+ toString(): string;
41
+ /**
42
+ * JSON representation (excludes password)
43
+ */
44
+ toJSON(): Record<string, unknown>;
45
+ }
46
+ //# sourceMappingURL=basic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"basic.d.ts","sourceRoot":"","sources":["../../src/auth/basic.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAS;IAEzB,YAAY,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAS7C;IAED;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC,SAAS,CAAC,CAMvC;IAED;;OAEG;IACH,aAAa,IAAI,MAAM,CAItB;IAED;;OAEG;IACH,QAAQ,IAAI,OAAO,CASlB;IAED;;OAEG;IACH,OAAO,IAAI,MAAM,CAEhB;IAED;;OAEG;IACH,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAS1D;IAED;;OAEG;IACH,QAAQ,IAAI,MAAM,CAEjB;IAED;;OAEG;IACH,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAMhC;CACF"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Basic authentication handler for GitHub API
3
+ * Supports username/password or username/personal access token
4
+ */
5
+ /**
6
+ * Handler for HTTP Basic authentication
7
+ */
8
+ export class BasicAuthHandler {
9
+ username;
10
+ password;
11
+ constructor(username, password) {
12
+ if (!username || username.trim() === '') {
13
+ throw new Error('Username cannot be empty');
14
+ }
15
+ if (!password || password.trim() === '') {
16
+ throw new Error('Password cannot be empty');
17
+ }
18
+ this.username = username;
19
+ this.password = password;
20
+ }
21
+ /**
22
+ * Authenticate and return auth object
23
+ */
24
+ async authenticate() {
25
+ return {
26
+ type: 'basic',
27
+ username: this.username,
28
+ password: this.password
29
+ };
30
+ }
31
+ /**
32
+ * Get base64-encoded Basic auth header value
33
+ */
34
+ getAuthHeader() {
35
+ const credentials = `${this.username}:${this.password}`;
36
+ const encoded = Buffer.from(credentials).toString('base64');
37
+ return `Basic ${encoded}`;
38
+ }
39
+ /**
40
+ * Validate credentials format
41
+ */
42
+ validate() {
43
+ // Check for invalid characters (newlines, etc.)
44
+ if (this.username.includes('\n') || this.username.includes('\r')) {
45
+ return false;
46
+ }
47
+ if (this.password.includes('\n') || this.password.includes('\r')) {
48
+ return false;
49
+ }
50
+ return true;
51
+ }
52
+ /**
53
+ * Get authentication type
54
+ */
55
+ getType() {
56
+ return 'basic';
57
+ }
58
+ /**
59
+ * Update credentials (for rotation)
60
+ */
61
+ updateCredentials(username, password) {
62
+ if (!username || username.trim() === '') {
63
+ throw new Error('Username cannot be empty');
64
+ }
65
+ if (!password || password.trim() === '') {
66
+ throw new Error('Password cannot be empty');
67
+ }
68
+ this.username = username;
69
+ this.password = password;
70
+ }
71
+ /**
72
+ * String representation (masks password)
73
+ */
74
+ toString() {
75
+ return `BasicAuth(username=${this.username}, password=***)`;
76
+ }
77
+ /**
78
+ * JSON representation (excludes password)
79
+ */
80
+ toJSON() {
81
+ return {
82
+ type: 'basic',
83
+ username: this.username
84
+ // password intentionally excluded
85
+ };
86
+ }
87
+ }
88
+ //# sourceMappingURL=basic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"basic.js","sourceRoot":"","sources":["../../src/auth/basic.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH;;GAEG;AACH,MAAM,OAAO,gBAAgB;IACnB,QAAQ,CAAS;IACjB,QAAQ,CAAS;IAEzB,YAAY,QAAgB,EAAE,QAAgB,EAAE;QAC9C,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAC9C,CAAC;QACD,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAC9C,CAAC;QACD,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAAA,CAC1B;IAED;;OAEG;IACH,KAAK,CAAC,YAAY,GAAuB;QACvC,OAAO;YACL,IAAI,EAAE,OAAO;YACb,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,QAAQ,EAAE,IAAI,CAAC,QAAQ;SACxB,CAAC;IAAA,CACH;IAED;;OAEG;IACH,aAAa,GAAW;QACtB,MAAM,WAAW,GAAG,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QACxD,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC5D,OAAO,SAAS,OAAO,EAAE,CAAC;IAAA,CAC3B;IAED;;OAEG;IACH,QAAQ,GAAY;QAClB,gDAAgD;QAChD,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACjE,OAAO,KAAK,CAAC;QACf,CAAC;QACD,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACjE,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,IAAI,CAAC;IAAA,CACb;IAED;;OAEG;IACH,OAAO,GAAW;QAChB,OAAO,OAAO,CAAC;IAAA,CAChB;IAED;;OAEG;IACH,iBAAiB,CAAC,QAAgB,EAAE,QAAgB,EAAQ;QAC1D,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAC9C,CAAC;QACD,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAC9C,CAAC;QACD,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAAA,CAC1B;IAED;;OAEG;IACH,QAAQ,GAAW;QACjB,OAAO,sBAAsB,IAAI,CAAC,QAAQ,iBAAiB,CAAC;IAAA,CAC7D;IAED;;OAEG;IACH,MAAM,GAA4B;QAChC,OAAO;YACL,IAAI,EAAE,OAAO;YACb,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,kCAAkC;SACnC,CAAC;IAAA,CACH;CACF"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * OAuth 2.0 authentication handler for GitHub
3
+ * Supports authorization code flow and token refresh
4
+ */
5
+ export interface OAuthConfig {
6
+ clientId: string;
7
+ clientSecret: string;
8
+ redirectUri: string;
9
+ }
10
+ export interface OAuthAuth {
11
+ type: 'oauth';
12
+ token: string;
13
+ tokenType: string;
14
+ scope?: string | undefined;
15
+ expiresIn?: number | undefined;
16
+ refreshToken?: string | undefined;
17
+ }
18
+ /**
19
+ * Handler for OAuth 2.0 authentication
20
+ */
21
+ export declare class OAuthHandler {
22
+ private config;
23
+ private readonly GITHUB_OAUTH_URL;
24
+ constructor(config: OAuthConfig);
25
+ /**
26
+ * Exchange authorization code for access token
27
+ */
28
+ authenticate(code: string): Promise<OAuthAuth>;
29
+ /**
30
+ * Generate authorization URL for OAuth flow
31
+ */
32
+ getAuthorizationUrl(scopes: string[], state?: string): string;
33
+ /**
34
+ * Refresh an expired access token
35
+ */
36
+ refreshToken(refreshToken: string): Promise<OAuthAuth>;
37
+ /**
38
+ * Validate OAuth configuration
39
+ */
40
+ validate(): boolean;
41
+ /**
42
+ * Get authentication type
43
+ */
44
+ getType(): string;
45
+ private exchangeCodeForToken;
46
+ private performTokenRefresh;
47
+ }
48
+ //# sourceMappingURL=oauth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../../src/auth/oauth.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACnC;AAUD;;GAEG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAoC;IAErE,YAAY,MAAM,EAAE,WAAW,EAQ9B;IAED;;OAEG;IACG,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAenD;IAED;;OAEG;IACH,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAY5D;IAED;;OAEG;IACG,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAc3D;IAED;;OAEG;IACH,QAAQ,IAAI,OAAO,CAQlB;IAED;;OAEG;IACH,OAAO,IAAI,MAAM,CAEhB;YAKa,oBAAoB;YA+BpB,mBAAmB;CA2BlC"}
@@ -0,0 +1,139 @@
1
+ /**
2
+ * OAuth 2.0 authentication handler for GitHub
3
+ * Supports authorization code flow and token refresh
4
+ */
5
+ /**
6
+ * Handler for OAuth 2.0 authentication
7
+ */
8
+ export class OAuthHandler {
9
+ config;
10
+ GITHUB_OAUTH_URL = 'https://github.com/login/oauth';
11
+ constructor(config) {
12
+ if (!config.clientId || config.clientId.trim() === '') {
13
+ throw new Error('clientId is required');
14
+ }
15
+ if (!config.clientSecret || config.clientSecret.trim() === '') {
16
+ throw new Error('clientSecret is required');
17
+ }
18
+ this.config = config;
19
+ }
20
+ /**
21
+ * Exchange authorization code for access token
22
+ */
23
+ async authenticate(code) {
24
+ if (!code || code.trim() === '') {
25
+ throw new Error('Authorization code is required');
26
+ }
27
+ const tokenResponse = await this.exchangeCodeForToken(code);
28
+ return {
29
+ type: 'oauth',
30
+ token: tokenResponse.access_token,
31
+ tokenType: tokenResponse.token_type,
32
+ scope: tokenResponse.scope,
33
+ expiresIn: tokenResponse.expires_in,
34
+ refreshToken: tokenResponse.refresh_token
35
+ };
36
+ }
37
+ /**
38
+ * Generate authorization URL for OAuth flow
39
+ */
40
+ getAuthorizationUrl(scopes, state) {
41
+ const params = new URLSearchParams({
42
+ client_id: this.config.clientId,
43
+ redirect_uri: this.config.redirectUri,
44
+ scope: scopes.join(' ')
45
+ });
46
+ if (state) {
47
+ params.append('state', state);
48
+ }
49
+ return `${this.GITHUB_OAUTH_URL}/authorize?${params.toString()}`;
50
+ }
51
+ /**
52
+ * Refresh an expired access token
53
+ */
54
+ async refreshToken(refreshToken) {
55
+ if (!refreshToken || refreshToken.trim() === '') {
56
+ throw new Error('Refresh token is required');
57
+ }
58
+ const tokenResponse = await this.performTokenRefresh(refreshToken);
59
+ return {
60
+ type: 'oauth',
61
+ token: tokenResponse.access_token,
62
+ tokenType: tokenResponse.token_type,
63
+ scope: tokenResponse.scope,
64
+ expiresIn: tokenResponse.expires_in
65
+ };
66
+ }
67
+ /**
68
+ * Validate OAuth configuration
69
+ */
70
+ validate() {
71
+ try {
72
+ // Validate redirect URI format
73
+ new URL(this.config.redirectUri);
74
+ return true;
75
+ }
76
+ catch {
77
+ return false;
78
+ }
79
+ }
80
+ /**
81
+ * Get authentication type
82
+ */
83
+ getType() {
84
+ return 'oauth';
85
+ }
86
+ /**
87
+ * Exchange authorization code for token (internal)
88
+ */
89
+ async exchangeCodeForToken(code) {
90
+ const response = await fetch(`${this.GITHUB_OAUTH_URL}/access_token`, {
91
+ method: 'POST',
92
+ headers: {
93
+ 'Content-Type': 'application/json',
94
+ Accept: 'application/json'
95
+ },
96
+ body: JSON.stringify({
97
+ client_id: this.config.clientId,
98
+ client_secret: this.config.clientSecret,
99
+ code: code,
100
+ redirect_uri: this.config.redirectUri
101
+ })
102
+ });
103
+ if (!response.ok) {
104
+ throw new Error(`Failed to exchange code for token: ${response.statusText}`);
105
+ }
106
+ const data = await response.json();
107
+ if (data.error) {
108
+ throw new Error(data.error_description || data.error);
109
+ }
110
+ return data;
111
+ }
112
+ /**
113
+ * Perform token refresh (internal)
114
+ */
115
+ async performTokenRefresh(refreshToken) {
116
+ const response = await fetch(`${this.GITHUB_OAUTH_URL}/access_token`, {
117
+ method: 'POST',
118
+ headers: {
119
+ 'Content-Type': 'application/json',
120
+ Accept: 'application/json'
121
+ },
122
+ body: JSON.stringify({
123
+ client_id: this.config.clientId,
124
+ client_secret: this.config.clientSecret,
125
+ grant_type: 'refresh_token',
126
+ refresh_token: refreshToken
127
+ })
128
+ });
129
+ if (!response.ok) {
130
+ throw new Error(`Failed to refresh token: ${response.statusText}`);
131
+ }
132
+ const data = await response.json();
133
+ if (data.error) {
134
+ throw new Error(data.error_description || data.error);
135
+ }
136
+ return data;
137
+ }
138
+ }
139
+ //# sourceMappingURL=oauth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth.js","sourceRoot":"","sources":["../../src/auth/oauth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Token authentication handler for GitHub API
3
+ * Supports GitHub PAT tokens, fine-grained tokens, and API keys
4
+ */
5
+ export interface TokenAuth {
6
+ type: 'token';
7
+ token: string;
8
+ }
9
+ /**
10
+ * Handler for token-based authentication (GitHub PAT, API keys)
11
+ */
12
+ export declare class TokenAuthHandler {
13
+ private token;
14
+ private readonly GITHUB_TOKEN_PREFIXES;
15
+ constructor(token: string);
16
+ /**
17
+ * Authenticate and return auth object
18
+ */
19
+ authenticate(): Promise<TokenAuth>;
20
+ /**
21
+ * Validate token format
22
+ */
23
+ validate(): boolean;
24
+ /**
25
+ * Get authentication type
26
+ */
27
+ getType(): string;
28
+ /**
29
+ * Update token (for rotation)
30
+ */
31
+ updateToken(newToken: string): void;
32
+ /**
33
+ * Get current token
34
+ *
35
+ * @warning This method exposes the raw token value. Use with caution and avoid
36
+ * logging or displaying the token. Prefer using authenticate() for auth operations.
37
+ */
38
+ getToken(): string;
39
+ }
40
+ //# sourceMappingURL=token.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../../src/auth/token.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAOpC;IAEF,YAAY,KAAK,EAAE,MAAM,EAKxB;IAED;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC,SAAS,CAAC,CAKvC;IAED;;OAEG;IACH,QAAQ,IAAI,OAAO,CAQlB;IAED;;OAEG;IACH,OAAO,IAAI,MAAM,CAEhB;IAED;;OAEG;IACH,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAKlC;IAED;;;;;OAKG;IACH,QAAQ,IAAI,MAAM,CAEjB;CACF"}