@stoneforge/quarry 1.12.0 → 1.14.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 (199) hide show
  1. package/README.md +2 -0
  2. package/dist/api/quarry-api.d.ts +9 -1
  3. package/dist/api/quarry-api.d.ts.map +1 -1
  4. package/dist/api/quarry-api.js +21 -2
  5. package/dist/api/quarry-api.js.map +1 -1
  6. package/dist/api/types.d.ts +8 -1
  7. package/dist/api/types.d.ts.map +1 -1
  8. package/dist/api/types.js.map +1 -1
  9. package/dist/cli/commands/auto-link-helper.d.ts +33 -0
  10. package/dist/cli/commands/auto-link-helper.d.ts.map +1 -0
  11. package/dist/cli/commands/auto-link-helper.js +74 -0
  12. package/dist/cli/commands/auto-link-helper.js.map +1 -0
  13. package/dist/cli/commands/crud.d.ts +3 -0
  14. package/dist/cli/commands/crud.d.ts.map +1 -1
  15. package/dist/cli/commands/crud.js +144 -15
  16. package/dist/cli/commands/crud.js.map +1 -1
  17. package/dist/cli/commands/docs.js +2 -2
  18. package/dist/cli/commands/docs.js.map +1 -1
  19. package/dist/cli/commands/document.js +1 -1
  20. package/dist/cli/commands/document.js.map +1 -1
  21. package/dist/cli/commands/entity.js +1 -1
  22. package/dist/cli/commands/entity.js.map +1 -1
  23. package/dist/cli/commands/external-sync.d.ts +18 -0
  24. package/dist/cli/commands/external-sync.d.ts.map +1 -0
  25. package/dist/cli/commands/external-sync.js +2499 -0
  26. package/dist/cli/commands/external-sync.js.map +1 -0
  27. package/dist/cli/commands/library.js +1 -1
  28. package/dist/cli/commands/library.js.map +1 -1
  29. package/dist/cli/commands/message.js +2 -2
  30. package/dist/cli/commands/message.js.map +1 -1
  31. package/dist/cli/commands/serve.d.ts.map +1 -1
  32. package/dist/cli/commands/serve.js +2 -0
  33. package/dist/cli/commands/serve.js.map +1 -1
  34. package/dist/cli/commands/task.d.ts.map +1 -1
  35. package/dist/cli/commands/task.js +7 -4
  36. package/dist/cli/commands/task.js.map +1 -1
  37. package/dist/cli/commands/team.js +1 -1
  38. package/dist/cli/commands/team.js.map +1 -1
  39. package/dist/cli/commands/workflow.js +1 -1
  40. package/dist/cli/commands/workflow.js.map +1 -1
  41. package/dist/cli/runner.d.ts.map +1 -1
  42. package/dist/cli/runner.js +3 -0
  43. package/dist/cli/runner.js.map +1 -1
  44. package/dist/cli/utils/progress.d.ts +30 -0
  45. package/dist/cli/utils/progress.d.ts.map +1 -0
  46. package/dist/cli/utils/progress.js +47 -0
  47. package/dist/cli/utils/progress.js.map +1 -0
  48. package/dist/config/config.d.ts.map +1 -1
  49. package/dist/config/config.js +34 -0
  50. package/dist/config/config.js.map +1 -1
  51. package/dist/config/defaults.d.ts +13 -1
  52. package/dist/config/defaults.d.ts.map +1 -1
  53. package/dist/config/defaults.js +22 -0
  54. package/dist/config/defaults.js.map +1 -1
  55. package/dist/config/file.d.ts.map +1 -1
  56. package/dist/config/file.js +71 -0
  57. package/dist/config/file.js.map +1 -1
  58. package/dist/config/index.d.ts +3 -3
  59. package/dist/config/index.d.ts.map +1 -1
  60. package/dist/config/index.js +2 -2
  61. package/dist/config/index.js.map +1 -1
  62. package/dist/config/merge.d.ts.map +1 -1
  63. package/dist/config/merge.js +52 -1
  64. package/dist/config/merge.js.map +1 -1
  65. package/dist/config/types.d.ts +68 -1
  66. package/dist/config/types.d.ts.map +1 -1
  67. package/dist/config/types.js +33 -0
  68. package/dist/config/types.js.map +1 -1
  69. package/dist/config/validation.d.ts.map +1 -1
  70. package/dist/config/validation.js +64 -1
  71. package/dist/config/validation.js.map +1 -1
  72. package/dist/external-sync/adapters/document-sync-adapter.d.ts +150 -0
  73. package/dist/external-sync/adapters/document-sync-adapter.d.ts.map +1 -0
  74. package/dist/external-sync/adapters/document-sync-adapter.js +325 -0
  75. package/dist/external-sync/adapters/document-sync-adapter.js.map +1 -0
  76. package/dist/external-sync/adapters/task-sync-adapter.d.ts +177 -0
  77. package/dist/external-sync/adapters/task-sync-adapter.d.ts.map +1 -0
  78. package/dist/external-sync/adapters/task-sync-adapter.js +353 -0
  79. package/dist/external-sync/adapters/task-sync-adapter.js.map +1 -0
  80. package/dist/external-sync/auto-link.d.ts +66 -0
  81. package/dist/external-sync/auto-link.d.ts.map +1 -0
  82. package/dist/external-sync/auto-link.js +98 -0
  83. package/dist/external-sync/auto-link.js.map +1 -0
  84. package/dist/external-sync/conflict-resolver.d.ts +170 -0
  85. package/dist/external-sync/conflict-resolver.d.ts.map +1 -0
  86. package/dist/external-sync/conflict-resolver.js +580 -0
  87. package/dist/external-sync/conflict-resolver.js.map +1 -0
  88. package/dist/external-sync/index.d.ts +23 -0
  89. package/dist/external-sync/index.d.ts.map +1 -0
  90. package/dist/external-sync/index.js +24 -0
  91. package/dist/external-sync/index.js.map +1 -0
  92. package/dist/external-sync/provider-registry.d.ts +113 -0
  93. package/dist/external-sync/provider-registry.d.ts.map +1 -0
  94. package/dist/external-sync/provider-registry.js +205 -0
  95. package/dist/external-sync/provider-registry.js.map +1 -0
  96. package/dist/external-sync/providers/folder/folder-document-adapter.d.ts +97 -0
  97. package/dist/external-sync/providers/folder/folder-document-adapter.d.ts.map +1 -0
  98. package/dist/external-sync/providers/folder/folder-document-adapter.js +261 -0
  99. package/dist/external-sync/providers/folder/folder-document-adapter.js.map +1 -0
  100. package/dist/external-sync/providers/folder/folder-fs.d.ts +146 -0
  101. package/dist/external-sync/providers/folder/folder-fs.d.ts.map +1 -0
  102. package/dist/external-sync/providers/folder/folder-fs.js +300 -0
  103. package/dist/external-sync/providers/folder/folder-fs.js.map +1 -0
  104. package/dist/external-sync/providers/folder/folder-provider.d.ts +28 -0
  105. package/dist/external-sync/providers/folder/folder-provider.d.ts.map +1 -0
  106. package/dist/external-sync/providers/folder/folder-provider.js +87 -0
  107. package/dist/external-sync/providers/folder/folder-provider.js.map +1 -0
  108. package/dist/external-sync/providers/folder/index.d.ts +11 -0
  109. package/dist/external-sync/providers/folder/index.d.ts.map +1 -0
  110. package/dist/external-sync/providers/folder/index.js +13 -0
  111. package/dist/external-sync/providers/folder/index.js.map +1 -0
  112. package/dist/external-sync/providers/github/github-api.d.ts +271 -0
  113. package/dist/external-sync/providers/github/github-api.d.ts.map +1 -0
  114. package/dist/external-sync/providers/github/github-api.js +366 -0
  115. package/dist/external-sync/providers/github/github-api.js.map +1 -0
  116. package/dist/external-sync/providers/github/github-field-map.d.ts +76 -0
  117. package/dist/external-sync/providers/github/github-field-map.d.ts.map +1 -0
  118. package/dist/external-sync/providers/github/github-field-map.js +157 -0
  119. package/dist/external-sync/providers/github/github-field-map.js.map +1 -0
  120. package/dist/external-sync/providers/github/github-provider.d.ts +36 -0
  121. package/dist/external-sync/providers/github/github-provider.d.ts.map +1 -0
  122. package/dist/external-sync/providers/github/github-provider.js +212 -0
  123. package/dist/external-sync/providers/github/github-provider.js.map +1 -0
  124. package/dist/external-sync/providers/github/github-task-adapter.d.ts +135 -0
  125. package/dist/external-sync/providers/github/github-task-adapter.d.ts.map +1 -0
  126. package/dist/external-sync/providers/github/github-task-adapter.js +374 -0
  127. package/dist/external-sync/providers/github/github-task-adapter.js.map +1 -0
  128. package/dist/external-sync/providers/github/index.d.ts +12 -0
  129. package/dist/external-sync/providers/github/index.d.ts.map +1 -0
  130. package/dist/external-sync/providers/github/index.js +15 -0
  131. package/dist/external-sync/providers/github/index.js.map +1 -0
  132. package/dist/external-sync/providers/index.d.ts +13 -0
  133. package/dist/external-sync/providers/index.d.ts.map +1 -0
  134. package/dist/external-sync/providers/index.js +15 -0
  135. package/dist/external-sync/providers/index.js.map +1 -0
  136. package/dist/external-sync/providers/linear/index.d.ts +19 -0
  137. package/dist/external-sync/providers/linear/index.d.ts.map +1 -0
  138. package/dist/external-sync/providers/linear/index.js +19 -0
  139. package/dist/external-sync/providers/linear/index.js.map +1 -0
  140. package/dist/external-sync/providers/linear/linear-api.d.ts +252 -0
  141. package/dist/external-sync/providers/linear/linear-api.d.ts.map +1 -0
  142. package/dist/external-sync/providers/linear/linear-api.js +522 -0
  143. package/dist/external-sync/providers/linear/linear-api.js.map +1 -0
  144. package/dist/external-sync/providers/linear/linear-field-map.d.ts +135 -0
  145. package/dist/external-sync/providers/linear/linear-field-map.d.ts.map +1 -0
  146. package/dist/external-sync/providers/linear/linear-field-map.js +338 -0
  147. package/dist/external-sync/providers/linear/linear-field-map.js.map +1 -0
  148. package/dist/external-sync/providers/linear/linear-provider.d.ts +52 -0
  149. package/dist/external-sync/providers/linear/linear-provider.d.ts.map +1 -0
  150. package/dist/external-sync/providers/linear/linear-provider.js +169 -0
  151. package/dist/external-sync/providers/linear/linear-provider.js.map +1 -0
  152. package/dist/external-sync/providers/linear/linear-task-adapter.d.ts +190 -0
  153. package/dist/external-sync/providers/linear/linear-task-adapter.d.ts.map +1 -0
  154. package/dist/external-sync/providers/linear/linear-task-adapter.js +521 -0
  155. package/dist/external-sync/providers/linear/linear-task-adapter.js.map +1 -0
  156. package/dist/external-sync/providers/linear/linear-types.d.ts +114 -0
  157. package/dist/external-sync/providers/linear/linear-types.d.ts.map +1 -0
  158. package/dist/external-sync/providers/linear/linear-types.js +10 -0
  159. package/dist/external-sync/providers/linear/linear-types.js.map +1 -0
  160. package/dist/external-sync/providers/notion/index.d.ts +19 -0
  161. package/dist/external-sync/providers/notion/index.d.ts.map +1 -0
  162. package/dist/external-sync/providers/notion/index.js +20 -0
  163. package/dist/external-sync/providers/notion/index.js.map +1 -0
  164. package/dist/external-sync/providers/notion/notion-api.d.ts +253 -0
  165. package/dist/external-sync/providers/notion/notion-api.d.ts.map +1 -0
  166. package/dist/external-sync/providers/notion/notion-api.js +492 -0
  167. package/dist/external-sync/providers/notion/notion-api.js.map +1 -0
  168. package/dist/external-sync/providers/notion/notion-blocks.d.ts +93 -0
  169. package/dist/external-sync/providers/notion/notion-blocks.d.ts.map +1 -0
  170. package/dist/external-sync/providers/notion/notion-blocks.js +773 -0
  171. package/dist/external-sync/providers/notion/notion-blocks.js.map +1 -0
  172. package/dist/external-sync/providers/notion/notion-document-adapter.d.ts +176 -0
  173. package/dist/external-sync/providers/notion/notion-document-adapter.d.ts.map +1 -0
  174. package/dist/external-sync/providers/notion/notion-document-adapter.js +413 -0
  175. package/dist/external-sync/providers/notion/notion-document-adapter.js.map +1 -0
  176. package/dist/external-sync/providers/notion/notion-provider.d.ts +57 -0
  177. package/dist/external-sync/providers/notion/notion-provider.d.ts.map +1 -0
  178. package/dist/external-sync/providers/notion/notion-provider.js +159 -0
  179. package/dist/external-sync/providers/notion/notion-provider.js.map +1 -0
  180. package/dist/external-sync/providers/notion/notion-types.d.ts +388 -0
  181. package/dist/external-sync/providers/notion/notion-types.d.ts.map +1 -0
  182. package/dist/external-sync/providers/notion/notion-types.js +47 -0
  183. package/dist/external-sync/providers/notion/notion-types.js.map +1 -0
  184. package/dist/external-sync/sync-engine.d.ts +364 -0
  185. package/dist/external-sync/sync-engine.d.ts.map +1 -0
  186. package/dist/external-sync/sync-engine.js +1154 -0
  187. package/dist/external-sync/sync-engine.js.map +1 -0
  188. package/dist/index.d.ts +1 -0
  189. package/dist/index.d.ts.map +1 -1
  190. package/dist/index.js +2 -0
  191. package/dist/index.js.map +1 -1
  192. package/dist/server/index.js +8 -8
  193. package/dist/server/index.js.map +1 -1
  194. package/dist/services/inbox.js +1 -1
  195. package/dist/sync/hash.d.ts +5 -0
  196. package/dist/sync/hash.d.ts.map +1 -1
  197. package/dist/sync/hash.js +21 -2
  198. package/dist/sync/hash.js.map +1 -1
  199. package/package.json +10 -12
@@ -0,0 +1,271 @@
1
+ /**
2
+ * GitHub REST API Client
3
+ *
4
+ * Pure fetch-based client for GitHub issue operations.
5
+ * Supports Personal Access Token (PAT) auth, rate limit handling,
6
+ * and configurable base URL for GitHub Enterprise.
7
+ *
8
+ * No external dependencies — uses only the standard fetch API.
9
+ */
10
+ /**
11
+ * Minimal type matching the fields we use from GitHub's issue response.
12
+ * Does not attempt to type the full GitHub API response.
13
+ */
14
+ export interface GitHubIssue {
15
+ /** GitHub's internal issue ID */
16
+ readonly id: number;
17
+ /** Issue number within the repository */
18
+ readonly number: number;
19
+ /** Issue title */
20
+ readonly title: string;
21
+ /** Issue body/description (markdown) */
22
+ readonly body: string | null;
23
+ /** Issue state */
24
+ readonly state: 'open' | 'closed';
25
+ /** Labels attached to the issue */
26
+ readonly labels: readonly GitHubLabel[];
27
+ /** Users assigned to the issue */
28
+ readonly assignees: readonly GitHubUser[];
29
+ /** URL to view the issue in a browser */
30
+ readonly html_url: string;
31
+ /** Creation timestamp (ISO 8601) */
32
+ readonly created_at: string;
33
+ /** Last update timestamp (ISO 8601) */
34
+ readonly updated_at: string;
35
+ /** Closure timestamp (ISO 8601), null if still open */
36
+ readonly closed_at: string | null;
37
+ }
38
+ /**
39
+ * Minimal GitHub label representation
40
+ */
41
+ export interface GitHubLabel {
42
+ readonly id: number;
43
+ readonly name: string;
44
+ readonly color: string;
45
+ readonly description: string | null;
46
+ }
47
+ /**
48
+ * Minimal GitHub user representation
49
+ */
50
+ export interface GitHubUser {
51
+ readonly login: string;
52
+ readonly id: number;
53
+ }
54
+ /**
55
+ * Options for listing issues
56
+ */
57
+ export interface ListIssuesOptions {
58
+ /** Only return issues updated after this ISO 8601 timestamp */
59
+ since?: string;
60
+ /** Filter by state */
61
+ state?: 'open' | 'closed' | 'all';
62
+ /** Results per page (max 100, default 30) */
63
+ per_page?: number;
64
+ /** Page number for manual pagination */
65
+ page?: number;
66
+ }
67
+ /**
68
+ * Input for creating a new label on a repository
69
+ */
70
+ export interface CreateLabelInput {
71
+ /** Label name (required) */
72
+ name: string;
73
+ /** Label color as hex string without '#' prefix (e.g. '0075ca') */
74
+ color: string;
75
+ /** Optional description for the label */
76
+ description?: string;
77
+ }
78
+ /**
79
+ * Input for creating a new issue
80
+ */
81
+ export interface CreateIssueInput {
82
+ /** Issue title (required) */
83
+ title: string;
84
+ /** Issue body/description */
85
+ body?: string;
86
+ /** Label names to attach */
87
+ labels?: string[];
88
+ /** Usernames to assign */
89
+ assignees?: string[];
90
+ }
91
+ /**
92
+ * Input for updating an existing issue
93
+ */
94
+ export interface UpdateIssueInput {
95
+ /** Updated title */
96
+ title?: string;
97
+ /** Updated body */
98
+ body?: string;
99
+ /** Updated state */
100
+ state?: 'open' | 'closed';
101
+ /** Updated label names (replaces all labels) */
102
+ labels?: string[];
103
+ /** Updated assignees (replaces all assignees) */
104
+ assignees?: string[];
105
+ }
106
+ /**
107
+ * Rate limit information parsed from GitHub response headers
108
+ */
109
+ export interface RateLimitInfo {
110
+ /** Total requests allowed per hour */
111
+ readonly limit: number;
112
+ /** Requests remaining in the current window */
113
+ readonly remaining: number;
114
+ /** UTC epoch timestamp when the rate limit resets */
115
+ readonly reset: number;
116
+ }
117
+ /**
118
+ * Configuration for creating a GitHubApiClient
119
+ */
120
+ export interface GitHubApiClientOptions {
121
+ /** Personal Access Token for authentication */
122
+ token: string;
123
+ /** Base URL for GitHub API (default: https://api.github.com) */
124
+ apiBaseUrl?: string;
125
+ /** Remaining requests threshold to trigger warnings (default: 10) */
126
+ rateLimitWarningThreshold?: number;
127
+ }
128
+ /**
129
+ * Typed error for GitHub API failures.
130
+ * Wraps fetch errors with status code, message, and rate limit info.
131
+ */
132
+ export declare class GitHubApiError extends Error {
133
+ /** HTTP status code from GitHub's response */
134
+ readonly status: number;
135
+ /** Human-readable error message from GitHub */
136
+ readonly statusText: string;
137
+ /** Rate limit information at the time of the error */
138
+ readonly rateLimit: RateLimitInfo | null;
139
+ /** Parsed error body from GitHub (if available) */
140
+ readonly responseBody: Record<string, unknown> | null;
141
+ constructor(message: string, status: number, statusText: string, rateLimit?: RateLimitInfo | null, responseBody?: Record<string, unknown> | null, cause?: Error);
142
+ /**
143
+ * Whether this error is due to rate limiting
144
+ */
145
+ get isRateLimited(): boolean;
146
+ /**
147
+ * Whether this error is due to authentication failure
148
+ */
149
+ get isAuthError(): boolean;
150
+ /**
151
+ * Whether this error is a not-found response
152
+ */
153
+ get isNotFound(): boolean;
154
+ /**
155
+ * Returns a JSON-serializable representation of the error
156
+ */
157
+ toJSON(): {
158
+ name: string;
159
+ message: string;
160
+ status: number;
161
+ statusText: string;
162
+ rateLimit: RateLimitInfo | null;
163
+ responseBody: Record<string, unknown> | null;
164
+ };
165
+ }
166
+ /**
167
+ * Type guard for GitHubApiError
168
+ */
169
+ export declare function isGitHubApiError(error: unknown): error is GitHubApiError;
170
+ /**
171
+ * Fetch-based GitHub REST API client for issue operations.
172
+ *
173
+ * Features:
174
+ * - Personal Access Token (PAT) authentication
175
+ * - Rate limit tracking with warnings when approaching limit
176
+ * - Configurable base URL for GitHub Enterprise
177
+ * - Typed errors with status code and rate limit info
178
+ * - Automatic pagination for listing issues
179
+ *
180
+ * @example
181
+ * ```typescript
182
+ * const client = new GitHubApiClient({ token: 'ghp_...' });
183
+ * const issue = await client.getIssue('owner', 'repo', 42);
184
+ * const issues = await client.listIssues('owner', 'repo', { state: 'open' });
185
+ * ```
186
+ */
187
+ export declare class GitHubApiClient {
188
+ private readonly token;
189
+ private readonly apiBaseUrl;
190
+ private readonly rateLimitWarningThreshold;
191
+ /** Most recently observed rate limit info (updated after each request) */
192
+ private lastRateLimit;
193
+ constructor(options: GitHubApiClientOptions);
194
+ /**
195
+ * Returns the most recently observed rate limit info, or null if no requests have been made.
196
+ */
197
+ getRateLimit(): RateLimitInfo | null;
198
+ /**
199
+ * Fetch a single issue by number.
200
+ *
201
+ * GET /repos/{owner}/{repo}/issues/{issue_number}
202
+ */
203
+ getIssue(owner: string, repo: string, issueNumber: number): Promise<GitHubIssue>;
204
+ /**
205
+ * List issues for a repository.
206
+ *
207
+ * GET /repos/{owner}/{repo}/issues?since=...&state=all
208
+ *
209
+ * When no explicit `page` is provided, this method automatically iterates
210
+ * through all pages using the Link header and returns every matching issue.
211
+ * When a `page` is specified, only that single page is returned.
212
+ */
213
+ listIssues(owner: string, repo: string, options?: ListIssuesOptions): Promise<GitHubIssue[]>;
214
+ /**
215
+ * Create a new issue.
216
+ *
217
+ * POST /repos/{owner}/{repo}/issues
218
+ */
219
+ createIssue(owner: string, repo: string, input: CreateIssueInput): Promise<GitHubIssue>;
220
+ /**
221
+ * Update an existing issue.
222
+ *
223
+ * PATCH /repos/{owner}/{repo}/issues/{issue_number}
224
+ */
225
+ updateIssue(owner: string, repo: string, issueNumber: number, updates: UpdateIssueInput): Promise<GitHubIssue>;
226
+ /**
227
+ * List all labels for a repository.
228
+ *
229
+ * GET /repos/{owner}/{repo}/labels
230
+ *
231
+ * Auto-paginates through all pages to return the complete label set.
232
+ */
233
+ getLabels(owner: string, repo: string): Promise<GitHubLabel[]>;
234
+ /**
235
+ * Create a new label on a repository.
236
+ *
237
+ * POST /repos/{owner}/{repo}/labels
238
+ */
239
+ createLabel(owner: string, repo: string, input: CreateLabelInput): Promise<GitHubLabel>;
240
+ /**
241
+ * Performs a single HTTP request to the GitHub API.
242
+ */
243
+ private request;
244
+ /**
245
+ * Performs a paginated request, following Link headers to collect all pages.
246
+ */
247
+ private paginatedRequest;
248
+ /**
249
+ * Handles non-OK responses by throwing a GitHubApiError.
250
+ */
251
+ private handleErrorResponse;
252
+ /**
253
+ * Logs a warning when rate limit is approaching exhaustion.
254
+ */
255
+ private checkRateLimitWarning;
256
+ }
257
+ /**
258
+ * Parses rate limit information from GitHub response headers.
259
+ * Returns null if the headers are not present.
260
+ */
261
+ declare function parseRateLimitHeaders(headers: Headers): RateLimitInfo | null;
262
+ /**
263
+ * Parses the GitHub Link header to find the "next" page URL.
264
+ * Returns null if there is no next page.
265
+ *
266
+ * The Link header format is:
267
+ * <https://api.github.com/...?page=2>; rel="next", <https://api.github.com/...?page=5>; rel="last"
268
+ */
269
+ declare function parseLinkHeaderNext(linkHeader: string | null): string | null;
270
+ export { parseRateLimitHeaders, parseLinkHeaderNext };
271
+ //# sourceMappingURL=github-api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-api.d.ts","sourceRoot":"","sources":["../../../../src/external-sync/providers/github/github-api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,366 @@
1
+ /**
2
+ * GitHub REST API Client
3
+ *
4
+ * Pure fetch-based client for GitHub issue operations.
5
+ * Supports Personal Access Token (PAT) auth, rate limit handling,
6
+ * and configurable base URL for GitHub Enterprise.
7
+ *
8
+ * No external dependencies — uses only the standard fetch API.
9
+ */
10
+ // ============================================================================
11
+ // Error Types
12
+ // ============================================================================
13
+ /**
14
+ * Typed error for GitHub API failures.
15
+ * Wraps fetch errors with status code, message, and rate limit info.
16
+ */
17
+ export class GitHubApiError extends Error {
18
+ /** HTTP status code from GitHub's response */
19
+ status;
20
+ /** Human-readable error message from GitHub */
21
+ statusText;
22
+ /** Rate limit information at the time of the error */
23
+ rateLimit;
24
+ /** Parsed error body from GitHub (if available) */
25
+ responseBody;
26
+ constructor(message, status, statusText, rateLimit = null, responseBody = null, cause) {
27
+ super(message);
28
+ this.name = 'GitHubApiError';
29
+ this.status = status;
30
+ this.statusText = statusText;
31
+ this.rateLimit = rateLimit;
32
+ this.responseBody = responseBody;
33
+ this.cause = cause;
34
+ if (Error.captureStackTrace) {
35
+ Error.captureStackTrace(this, GitHubApiError);
36
+ }
37
+ }
38
+ /**
39
+ * Whether this error is due to rate limiting
40
+ */
41
+ get isRateLimited() {
42
+ return this.status === 403 && this.rateLimit !== null && this.rateLimit.remaining === 0;
43
+ }
44
+ /**
45
+ * Whether this error is due to authentication failure
46
+ */
47
+ get isAuthError() {
48
+ return this.status === 401;
49
+ }
50
+ /**
51
+ * Whether this error is a not-found response
52
+ */
53
+ get isNotFound() {
54
+ return this.status === 404;
55
+ }
56
+ /**
57
+ * Returns a JSON-serializable representation of the error
58
+ */
59
+ toJSON() {
60
+ return {
61
+ name: this.name,
62
+ message: this.message,
63
+ status: this.status,
64
+ statusText: this.statusText,
65
+ rateLimit: this.rateLimit,
66
+ responseBody: this.responseBody,
67
+ };
68
+ }
69
+ }
70
+ /**
71
+ * Type guard for GitHubApiError
72
+ */
73
+ export function isGitHubApiError(error) {
74
+ return error instanceof GitHubApiError;
75
+ }
76
+ // ============================================================================
77
+ // Rate Limit Warning Threshold
78
+ // ============================================================================
79
+ /** Default threshold of remaining requests before logging a warning */
80
+ const DEFAULT_RATE_LIMIT_WARNING_THRESHOLD = 10;
81
+ // ============================================================================
82
+ // Client Implementation
83
+ // ============================================================================
84
+ /**
85
+ * Fetch-based GitHub REST API client for issue operations.
86
+ *
87
+ * Features:
88
+ * - Personal Access Token (PAT) authentication
89
+ * - Rate limit tracking with warnings when approaching limit
90
+ * - Configurable base URL for GitHub Enterprise
91
+ * - Typed errors with status code and rate limit info
92
+ * - Automatic pagination for listing issues
93
+ *
94
+ * @example
95
+ * ```typescript
96
+ * const client = new GitHubApiClient({ token: 'ghp_...' });
97
+ * const issue = await client.getIssue('owner', 'repo', 42);
98
+ * const issues = await client.listIssues('owner', 'repo', { state: 'open' });
99
+ * ```
100
+ */
101
+ export class GitHubApiClient {
102
+ token;
103
+ apiBaseUrl;
104
+ rateLimitWarningThreshold;
105
+ /** Most recently observed rate limit info (updated after each request) */
106
+ lastRateLimit = null;
107
+ constructor(options) {
108
+ if (!options.token) {
109
+ throw new Error('GitHub API token is required');
110
+ }
111
+ this.token = options.token;
112
+ this.apiBaseUrl = (options.apiBaseUrl ?? 'https://api.github.com').replace(/\/$/, '');
113
+ this.rateLimitWarningThreshold =
114
+ options.rateLimitWarningThreshold ?? DEFAULT_RATE_LIMIT_WARNING_THRESHOLD;
115
+ }
116
+ /**
117
+ * Returns the most recently observed rate limit info, or null if no requests have been made.
118
+ */
119
+ getRateLimit() {
120
+ return this.lastRateLimit;
121
+ }
122
+ // --------------------------------------------------------------------------
123
+ // Public API Methods
124
+ // --------------------------------------------------------------------------
125
+ /**
126
+ * Fetch a single issue by number.
127
+ *
128
+ * GET /repos/{owner}/{repo}/issues/{issue_number}
129
+ */
130
+ async getIssue(owner, repo, issueNumber) {
131
+ return this.request('GET', `/repos/${enc(owner)}/${enc(repo)}/issues/${issueNumber}`);
132
+ }
133
+ /**
134
+ * List issues for a repository.
135
+ *
136
+ * GET /repos/{owner}/{repo}/issues?since=...&state=all
137
+ *
138
+ * When no explicit `page` is provided, this method automatically iterates
139
+ * through all pages using the Link header and returns every matching issue.
140
+ * When a `page` is specified, only that single page is returned.
141
+ */
142
+ async listIssues(owner, repo, options = {}) {
143
+ const params = new URLSearchParams();
144
+ if (options.since)
145
+ params.set('since', options.since);
146
+ if (options.state)
147
+ params.set('state', options.state);
148
+ if (options.per_page)
149
+ params.set('per_page', String(options.per_page));
150
+ // If a specific page was requested, fetch only that page
151
+ if (options.page !== undefined) {
152
+ params.set('page', String(options.page));
153
+ const path = `/repos/${enc(owner)}/${enc(repo)}/issues`;
154
+ const queryString = params.toString();
155
+ const url = queryString ? `${path}?${queryString}` : path;
156
+ return this.request('GET', url);
157
+ }
158
+ // Otherwise, auto-paginate through all pages
159
+ return this.paginatedRequest(`/repos/${enc(owner)}/${enc(repo)}/issues`, params);
160
+ }
161
+ /**
162
+ * Create a new issue.
163
+ *
164
+ * POST /repos/{owner}/{repo}/issues
165
+ */
166
+ async createIssue(owner, repo, input) {
167
+ return this.request('POST', `/repos/${enc(owner)}/${enc(repo)}/issues`, input);
168
+ }
169
+ /**
170
+ * Update an existing issue.
171
+ *
172
+ * PATCH /repos/{owner}/{repo}/issues/{issue_number}
173
+ */
174
+ async updateIssue(owner, repo, issueNumber, updates) {
175
+ return this.request('PATCH', `/repos/${enc(owner)}/${enc(repo)}/issues/${issueNumber}`, updates);
176
+ }
177
+ /**
178
+ * List all labels for a repository.
179
+ *
180
+ * GET /repos/{owner}/{repo}/labels
181
+ *
182
+ * Auto-paginates through all pages to return the complete label set.
183
+ */
184
+ async getLabels(owner, repo) {
185
+ return this.paginatedRequest(`/repos/${enc(owner)}/${enc(repo)}/labels`, new URLSearchParams());
186
+ }
187
+ /**
188
+ * Create a new label on a repository.
189
+ *
190
+ * POST /repos/{owner}/{repo}/labels
191
+ */
192
+ async createLabel(owner, repo, input) {
193
+ return this.request('POST', `/repos/${enc(owner)}/${enc(repo)}/labels`, input);
194
+ }
195
+ // --------------------------------------------------------------------------
196
+ // Internal: HTTP Request Handling
197
+ // --------------------------------------------------------------------------
198
+ /**
199
+ * Performs a single HTTP request to the GitHub API.
200
+ */
201
+ async request(method, path, body) {
202
+ const url = `${this.apiBaseUrl}${path}`;
203
+ const headers = {
204
+ Authorization: `Bearer ${this.token}`,
205
+ Accept: 'application/vnd.github+json',
206
+ 'X-GitHub-Api-Version': '2022-11-28',
207
+ };
208
+ if (body !== undefined) {
209
+ headers['Content-Type'] = 'application/json';
210
+ }
211
+ let response;
212
+ try {
213
+ response = await fetch(url, {
214
+ method,
215
+ headers,
216
+ body: body !== undefined ? JSON.stringify(body) : undefined,
217
+ });
218
+ }
219
+ catch (err) {
220
+ throw new GitHubApiError(`Network error requesting ${method} ${path}: ${err instanceof Error ? err.message : String(err)}`, 0, 'Network Error', null, null, err instanceof Error ? err : undefined);
221
+ }
222
+ // Parse rate limit headers from every response
223
+ const rateLimit = parseRateLimitHeaders(response.headers);
224
+ if (rateLimit) {
225
+ this.lastRateLimit = rateLimit;
226
+ this.checkRateLimitWarning(rateLimit, method, path);
227
+ }
228
+ if (!response.ok) {
229
+ await this.handleErrorResponse(response, rateLimit, method, path);
230
+ }
231
+ return (await response.json());
232
+ }
233
+ /**
234
+ * Performs a paginated request, following Link headers to collect all pages.
235
+ */
236
+ async paginatedRequest(basePath, params) {
237
+ const allItems = [];
238
+ // Start at page 1 if not set
239
+ if (!params.has('page')) {
240
+ params.set('page', '1');
241
+ }
242
+ // Default to 100 per page for efficiency if not set
243
+ if (!params.has('per_page')) {
244
+ params.set('per_page', '100');
245
+ }
246
+ let nextUrl = `${this.apiBaseUrl}${basePath}?${params.toString()}`;
247
+ while (nextUrl) {
248
+ const headers = {
249
+ Authorization: `Bearer ${this.token}`,
250
+ Accept: 'application/vnd.github+json',
251
+ 'X-GitHub-Api-Version': '2022-11-28',
252
+ };
253
+ let response;
254
+ try {
255
+ response = await fetch(nextUrl, { method: 'GET', headers });
256
+ }
257
+ catch (err) {
258
+ throw new GitHubApiError(`Network error during paginated request to ${nextUrl}: ${err instanceof Error ? err.message : String(err)}`, 0, 'Network Error', null, null, err instanceof Error ? err : undefined);
259
+ }
260
+ const rateLimit = parseRateLimitHeaders(response.headers);
261
+ if (rateLimit) {
262
+ this.lastRateLimit = rateLimit;
263
+ this.checkRateLimitWarning(rateLimit, 'GET', basePath);
264
+ }
265
+ if (!response.ok) {
266
+ await this.handleErrorResponse(response, rateLimit, 'GET', basePath);
267
+ }
268
+ const items = (await response.json());
269
+ allItems.push(...items);
270
+ // Parse Link header for next page
271
+ nextUrl = parseLinkHeaderNext(response.headers.get('Link'));
272
+ }
273
+ return allItems;
274
+ }
275
+ // --------------------------------------------------------------------------
276
+ // Internal: Error and Rate Limit Handling
277
+ // --------------------------------------------------------------------------
278
+ /**
279
+ * Handles non-OK responses by throwing a GitHubApiError.
280
+ */
281
+ async handleErrorResponse(response, rateLimit, method, path) {
282
+ let responseBody = null;
283
+ let errorMessage;
284
+ try {
285
+ responseBody = (await response.json());
286
+ errorMessage =
287
+ typeof responseBody.message === 'string'
288
+ ? responseBody.message
289
+ : `GitHub API error: ${response.status} ${response.statusText}`;
290
+ }
291
+ catch {
292
+ errorMessage = `GitHub API error: ${response.status} ${response.statusText}`;
293
+ }
294
+ // Special messaging for rate limit exhaustion
295
+ if (response.status === 403 && rateLimit && rateLimit.remaining === 0) {
296
+ const resetDate = new Date(rateLimit.reset * 1000);
297
+ errorMessage = `GitHub API rate limit exhausted. Resets at ${resetDate.toISOString()} (${rateLimit.reset}). ${errorMessage}`;
298
+ }
299
+ throw new GitHubApiError(`${method} ${path} failed: ${errorMessage}`, response.status, response.statusText, rateLimit, responseBody);
300
+ }
301
+ /**
302
+ * Logs a warning when rate limit is approaching exhaustion.
303
+ */
304
+ checkRateLimitWarning(rateLimit, method, path) {
305
+ if (rateLimit.remaining <= this.rateLimitWarningThreshold && rateLimit.remaining > 0) {
306
+ const resetDate = new Date(rateLimit.reset * 1000);
307
+ console.warn(`[GitHubApiClient] Rate limit warning: ${rateLimit.remaining}/${rateLimit.limit} requests remaining. ` +
308
+ `Resets at ${resetDate.toISOString()}. ` +
309
+ `Triggered by ${method} ${path}`);
310
+ }
311
+ }
312
+ }
313
+ // ============================================================================
314
+ // Utility Functions
315
+ // ============================================================================
316
+ /**
317
+ * URI-encodes a path segment for safe inclusion in URLs.
318
+ */
319
+ function enc(value) {
320
+ return encodeURIComponent(value);
321
+ }
322
+ /**
323
+ * Parses rate limit information from GitHub response headers.
324
+ * Returns null if the headers are not present.
325
+ */
326
+ function parseRateLimitHeaders(headers) {
327
+ const limit = headers.get('X-RateLimit-Limit');
328
+ const remaining = headers.get('X-RateLimit-Remaining');
329
+ const reset = headers.get('X-RateLimit-Reset');
330
+ if (limit === null || remaining === null || reset === null) {
331
+ return null;
332
+ }
333
+ const parsedLimit = parseInt(limit, 10);
334
+ const parsedRemaining = parseInt(remaining, 10);
335
+ const parsedReset = parseInt(reset, 10);
336
+ if (isNaN(parsedLimit) || isNaN(parsedRemaining) || isNaN(parsedReset)) {
337
+ return null;
338
+ }
339
+ return {
340
+ limit: parsedLimit,
341
+ remaining: parsedRemaining,
342
+ reset: parsedReset,
343
+ };
344
+ }
345
+ /**
346
+ * Parses the GitHub Link header to find the "next" page URL.
347
+ * Returns null if there is no next page.
348
+ *
349
+ * The Link header format is:
350
+ * <https://api.github.com/...?page=2>; rel="next", <https://api.github.com/...?page=5>; rel="last"
351
+ */
352
+ function parseLinkHeaderNext(linkHeader) {
353
+ if (!linkHeader)
354
+ return null;
355
+ const links = linkHeader.split(',');
356
+ for (const link of links) {
357
+ const match = link.match(/<([^>]+)>;\s*rel="next"/);
358
+ if (match) {
359
+ return match[1];
360
+ }
361
+ }
362
+ return null;
363
+ }
364
+ // Export utility functions for testing
365
+ export { parseRateLimitHeaders, parseLinkHeaderNext };
366
+ //# sourceMappingURL=github-api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-api.js","sourceRoot":"","sources":["../../../../src/external-sync/providers/github/github-api.ts"],"names":[],"mappings":"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"}