bktide 0.0.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 (160) hide show
  1. package/README.md +145 -0
  2. package/WORKFLOW_README.md +65 -0
  3. package/bin/alfred-entrypoint +54 -0
  4. package/dist/commands/BaseCommand.js +159 -0
  5. package/dist/commands/BaseCommand.js.map +1 -0
  6. package/dist/commands/BaseCommandHandler.js +80 -0
  7. package/dist/commands/BaseCommandHandler.js.map +1 -0
  8. package/dist/commands/BuildCommandHandler.js +28 -0
  9. package/dist/commands/BuildCommandHandler.js.map +1 -0
  10. package/dist/commands/HelloCommandHandler.js +6 -0
  11. package/dist/commands/HelloCommandHandler.js.map +1 -0
  12. package/dist/commands/ListAnnotations.js +60 -0
  13. package/dist/commands/ListAnnotations.js.map +1 -0
  14. package/dist/commands/ListBuilds.js +137 -0
  15. package/dist/commands/ListBuilds.js.map +1 -0
  16. package/dist/commands/ListOrganizations.js +27 -0
  17. package/dist/commands/ListOrganizations.js.map +1 -0
  18. package/dist/commands/ListPipelines.js +114 -0
  19. package/dist/commands/ListPipelines.js.map +1 -0
  20. package/dist/commands/ManageToken.js +180 -0
  21. package/dist/commands/ManageToken.js.map +1 -0
  22. package/dist/commands/OrganizationCommandHandler.js +53 -0
  23. package/dist/commands/OrganizationCommandHandler.js.map +1 -0
  24. package/dist/commands/PipelineCommandHandler.js +142 -0
  25. package/dist/commands/PipelineCommandHandler.js.map +1 -0
  26. package/dist/commands/ShowViewer.js +26 -0
  27. package/dist/commands/ShowViewer.js.map +1 -0
  28. package/dist/commands/UserBuildsCommandHandler.js +61 -0
  29. package/dist/commands/UserBuildsCommandHandler.js.map +1 -0
  30. package/dist/commands/ViewerBuildsCommandHandler.js +176 -0
  31. package/dist/commands/ViewerBuildsCommandHandler.js.map +1 -0
  32. package/dist/commands/ViewerCommandHandler.js +46 -0
  33. package/dist/commands/ViewerCommandHandler.js.map +1 -0
  34. package/dist/commands/index.js +8 -0
  35. package/dist/commands/index.js.map +1 -0
  36. package/dist/formatters/BaseFormatter.js +14 -0
  37. package/dist/formatters/BaseFormatter.js.map +1 -0
  38. package/dist/formatters/FormatterFactory.js +48 -0
  39. package/dist/formatters/FormatterFactory.js.map +1 -0
  40. package/dist/formatters/annotations/Formatter.js +10 -0
  41. package/dist/formatters/annotations/Formatter.js.map +1 -0
  42. package/dist/formatters/annotations/JsonFormatter.js +20 -0
  43. package/dist/formatters/annotations/JsonFormatter.js.map +1 -0
  44. package/dist/formatters/annotations/PlainTextFormatter.js +35 -0
  45. package/dist/formatters/annotations/PlainTextFormatter.js.map +1 -0
  46. package/dist/formatters/annotations/index.js +23 -0
  47. package/dist/formatters/annotations/index.js.map +1 -0
  48. package/dist/formatters/builds/AlfredFormatter.js +135 -0
  49. package/dist/formatters/builds/AlfredFormatter.js.map +1 -0
  50. package/dist/formatters/builds/Formatter.js +10 -0
  51. package/dist/formatters/builds/Formatter.js.map +1 -0
  52. package/dist/formatters/builds/JsonFormatter.js +44 -0
  53. package/dist/formatters/builds/JsonFormatter.js.map +1 -0
  54. package/dist/formatters/builds/PlainTextFormatter.js +113 -0
  55. package/dist/formatters/builds/PlainTextFormatter.js.map +1 -0
  56. package/dist/formatters/builds/index.js +26 -0
  57. package/dist/formatters/builds/index.js.map +1 -0
  58. package/dist/formatters/errors/AlfredFormatter.js +110 -0
  59. package/dist/formatters/errors/AlfredFormatter.js.map +1 -0
  60. package/dist/formatters/errors/Formatter.js +98 -0
  61. package/dist/formatters/errors/Formatter.js.map +1 -0
  62. package/dist/formatters/errors/JsonFormatter.js +63 -0
  63. package/dist/formatters/errors/JsonFormatter.js.map +1 -0
  64. package/dist/formatters/errors/PlainTextFormatter.js +52 -0
  65. package/dist/formatters/errors/PlainTextFormatter.js.map +1 -0
  66. package/dist/formatters/errors/index.js +26 -0
  67. package/dist/formatters/errors/index.js.map +1 -0
  68. package/dist/formatters/index.js +9 -0
  69. package/dist/formatters/index.js.map +1 -0
  70. package/dist/formatters/organizations/Formatter.js +10 -0
  71. package/dist/formatters/organizations/Formatter.js.map +1 -0
  72. package/dist/formatters/organizations/JsonFormatter.js +16 -0
  73. package/dist/formatters/organizations/JsonFormatter.js.map +1 -0
  74. package/dist/formatters/organizations/PlainTextFormatter.js +15 -0
  75. package/dist/formatters/organizations/PlainTextFormatter.js.map +1 -0
  76. package/dist/formatters/organizations/index.js +21 -0
  77. package/dist/formatters/organizations/index.js.map +1 -0
  78. package/dist/formatters/pipelines/AlfredFormatter.js +42 -0
  79. package/dist/formatters/pipelines/AlfredFormatter.js.map +1 -0
  80. package/dist/formatters/pipelines/Formatter.js +10 -0
  81. package/dist/formatters/pipelines/Formatter.js.map +1 -0
  82. package/dist/formatters/pipelines/JsonFormatter.js +13 -0
  83. package/dist/formatters/pipelines/JsonFormatter.js.map +1 -0
  84. package/dist/formatters/pipelines/PlainTextFormatter.js +47 -0
  85. package/dist/formatters/pipelines/PlainTextFormatter.js.map +1 -0
  86. package/dist/formatters/pipelines/index.js +28 -0
  87. package/dist/formatters/pipelines/index.js.map +1 -0
  88. package/dist/formatters/token/AlfredFormatter.js +191 -0
  89. package/dist/formatters/token/AlfredFormatter.js.map +1 -0
  90. package/dist/formatters/token/Formatter.js +13 -0
  91. package/dist/formatters/token/Formatter.js.map +1 -0
  92. package/dist/formatters/token/JsonFormatter.js +211 -0
  93. package/dist/formatters/token/JsonFormatter.js.map +1 -0
  94. package/dist/formatters/token/PlainTextFormatter.js +184 -0
  95. package/dist/formatters/token/PlainTextFormatter.js.map +1 -0
  96. package/dist/formatters/token/index.js +26 -0
  97. package/dist/formatters/token/index.js.map +1 -0
  98. package/dist/formatters/viewer/Formatter.js +10 -0
  99. package/dist/formatters/viewer/Formatter.js.map +1 -0
  100. package/dist/formatters/viewer/JsonFormatter.js +20 -0
  101. package/dist/formatters/viewer/JsonFormatter.js.map +1 -0
  102. package/dist/formatters/viewer/PlainTextFormatter.js +20 -0
  103. package/dist/formatters/viewer/PlainTextFormatter.js.map +1 -0
  104. package/dist/formatters/viewer/index.js +21 -0
  105. package/dist/formatters/viewer/index.js.map +1 -0
  106. package/dist/graphql/generated/fragment-masking.js +17 -0
  107. package/dist/graphql/generated/fragment-masking.js.map +1 -0
  108. package/dist/graphql/generated/gql.js +13 -0
  109. package/dist/graphql/generated/gql.js.map +1 -0
  110. package/dist/graphql/generated/graphql.js +852 -0
  111. package/dist/graphql/generated/graphql.js.map +1 -0
  112. package/dist/graphql/generated/index.js +3 -0
  113. package/dist/graphql/generated/index.js.map +1 -0
  114. package/dist/graphql/generated/sdk.js +872 -0
  115. package/dist/graphql/generated/sdk.js.map +1 -0
  116. package/dist/graphql/queries.js +138 -0
  117. package/dist/graphql/queries.js.map +1 -0
  118. package/dist/index.js +271 -0
  119. package/dist/index.js.map +1 -0
  120. package/dist/services/BuildkiteClient.js +520 -0
  121. package/dist/services/BuildkiteClient.js.map +1 -0
  122. package/dist/services/BuildkiteRestClient.js +244 -0
  123. package/dist/services/BuildkiteRestClient.js.map +1 -0
  124. package/dist/services/CacheManager.js +221 -0
  125. package/dist/services/CacheManager.js.map +1 -0
  126. package/dist/services/CredentialManager.js +158 -0
  127. package/dist/services/CredentialManager.js.map +1 -0
  128. package/dist/services/EnhancedBuildkiteClient.js +297 -0
  129. package/dist/services/EnhancedBuildkiteClient.js.map +1 -0
  130. package/dist/services/logger.js +107 -0
  131. package/dist/services/logger.js.map +1 -0
  132. package/dist/types/buildkite.js +5 -0
  133. package/dist/types/buildkite.js.map +1 -0
  134. package/dist/types/credentials.js +2 -0
  135. package/dist/types/credentials.js.map +1 -0
  136. package/dist/types/index.js +3 -0
  137. package/dist/types/index.js.map +1 -0
  138. package/dist/utils/cli-error-handler.js +172 -0
  139. package/dist/utils/cli-error-handler.js.map +1 -0
  140. package/dist/utils/errorUtils.js +59 -0
  141. package/dist/utils/errorUtils.js.map +1 -0
  142. package/dist/utils/parseBuildRef.js +31 -0
  143. package/dist/utils/parseBuildRef.js.map +1 -0
  144. package/dist/utils/textFormatter.js +53 -0
  145. package/dist/utils/textFormatter.js.map +1 -0
  146. package/dist/utils/xdgPaths.js +95 -0
  147. package/dist/utils/xdgPaths.js.map +1 -0
  148. package/env.example +66 -0
  149. package/icons/README.md +68 -0
  150. package/icons/blocked.png +0 -0
  151. package/icons/buildkite.png +0 -0
  152. package/icons/failed.png +0 -0
  153. package/icons/failing.png +0 -0
  154. package/icons/passed.png +0 -0
  155. package/icons/running.png +0 -0
  156. package/icons/scheduled.png +0 -0
  157. package/icons/skipped.png +0 -0
  158. package/icons/unknown.png +0 -0
  159. package/info.plist +734 -0
  160. package/package.json +87 -0
@@ -0,0 +1,520 @@
1
+ import { GraphQLClient } from 'graphql-request';
2
+ import { CacheManager } from './CacheManager.js';
3
+ // Import the queries - we'll use them for both string queries and typed SDK
4
+ import { GET_VIEWER, GET_ORGANIZATIONS, GET_PIPELINES, GET_BUILDS, GET_VIEWER_BUILDS, GET_BUILD_ANNOTATIONS } from '../graphql/queries.js';
5
+ import { logger } from './logger.js';
6
+ /**
7
+ * BuildkiteClient provides methods to interact with the Buildkite GraphQL API
8
+ */
9
+ export class BuildkiteClient {
10
+ client;
11
+ token;
12
+ baseUrl = 'https://graphql.buildkite.com/v1';
13
+ cacheManager = null;
14
+ debug = false;
15
+ rateLimitInfo = null;
16
+ /**
17
+ * Create a new BuildkiteClient
18
+ * @param token Your Buildkite API token
19
+ * @param options Configuration options
20
+ */
21
+ constructor(token, options, debug) {
22
+ this.token = token;
23
+ this.debug = debug || options?.debug || false;
24
+ if (this.debug) {
25
+ logger.debug('Initializing BuildkiteClient with options:', {
26
+ baseUrl: options?.baseUrl || this.baseUrl,
27
+ caching: options?.caching !== false,
28
+ debug: this.debug,
29
+ tokenLength: token ? token.length : 0
30
+ });
31
+ }
32
+ if (options?.baseUrl) {
33
+ this.baseUrl = options.baseUrl;
34
+ }
35
+ this.client = new GraphQLClient(this.baseUrl, {
36
+ headers: {
37
+ Authorization: `Bearer ${this.token}`,
38
+ },
39
+ });
40
+ // Initialize cache if caching is enabled
41
+ if (options?.caching !== false) {
42
+ if (this.debug) {
43
+ logger.debug('BuildkiteClient constructor - creating CacheManager');
44
+ }
45
+ this.cacheManager = new CacheManager(options?.cacheTTLs, this.debug);
46
+ // Initialize cache and set token hash (async, but we don't wait)
47
+ this.initCache();
48
+ }
49
+ else {
50
+ if (this.debug) {
51
+ logger.debug('BuildkiteClient constructor - caching disabled');
52
+ }
53
+ }
54
+ }
55
+ /**
56
+ * Initialize cache asynchronously
57
+ */
58
+ async initCache() {
59
+ if (this.cacheManager) {
60
+ await this.cacheManager.init();
61
+ await this.cacheManager.setTokenHash(this.token);
62
+ }
63
+ }
64
+ /**
65
+ * Execute a GraphQL query
66
+ * @param query The GraphQL query
67
+ * @param variables Variables for the query
68
+ * @returns The query response
69
+ */
70
+ async query(query, variables) {
71
+ try {
72
+ const startTime = process.hrtime.bigint();
73
+ const operationName = query.match(/query\s+(\w+)?/)?.[1] || 'UnnamedQuery';
74
+ if (this.debug) {
75
+ logger.debug(`🕒 Starting GraphQL query: ${operationName}`);
76
+ }
77
+ // Check if result is in cache
78
+ if (this.cacheManager) {
79
+ if (this.debug) {
80
+ logger.debug('query() - cacheManager exists, checking cache');
81
+ }
82
+ const cachedResult = await this.cacheManager.get(query, variables);
83
+ if (cachedResult) {
84
+ if (this.debug) {
85
+ logger.debug(`✅ Served from cache: ${operationName}`);
86
+ }
87
+ return cachedResult;
88
+ }
89
+ }
90
+ const response = await this.client.request(query, variables);
91
+ // Store result in cache if caching is enabled
92
+ if (this.cacheManager) {
93
+ await this.cacheManager.set(query, response, variables);
94
+ }
95
+ const endTime = process.hrtime.bigint();
96
+ const duration = Number(endTime - startTime) / 1000000; // Convert to milliseconds
97
+ if (this.debug) {
98
+ logger.debug(`✅ GraphQL query completed: ${operationName} (${duration.toFixed(2)}ms)`);
99
+ }
100
+ return response;
101
+ }
102
+ catch (error) {
103
+ const isAuthError = this.isAuthenticationError(error);
104
+ if (isAuthError && this.debug) {
105
+ logger.debug('Authentication error detected, not caching result');
106
+ }
107
+ if (this.debug) {
108
+ logger.error(error, 'Error in GraphQL query');
109
+ // Log raw error information
110
+ logger.debug('Raw error object:', {
111
+ error,
112
+ type: typeof error,
113
+ constructor: error?.constructor?.name,
114
+ keys: error && typeof error === 'object' ? Object.keys(error) : undefined
115
+ });
116
+ // Log more detailed error information
117
+ if (error instanceof Error && 'response' in error) {
118
+ const response = error.response;
119
+ logger.debug('GraphQL error details:', {
120
+ status: response?.status,
121
+ statusText: response?.statusText,
122
+ errors: response?.errors,
123
+ data: response?.data,
124
+ headers: response?.headers ? Object.fromEntries(response.headers.entries()) : undefined
125
+ });
126
+ }
127
+ }
128
+ throw error;
129
+ }
130
+ }
131
+ /**
132
+ * Check if an error is an authentication error
133
+ */
134
+ isAuthenticationError(error) {
135
+ // Check for common authentication error patterns
136
+ if (error.response?.errors) {
137
+ const errors = error.response.errors;
138
+ return errors.some((err) => err.message?.includes('unauthorized') ||
139
+ err.message?.includes('authentication') ||
140
+ err.message?.includes('permission') ||
141
+ err.message?.includes('invalid token'));
142
+ }
143
+ // Check for HTTP status codes that indicate auth issues
144
+ if (error.response?.status) {
145
+ const status = error.response.status;
146
+ return status === 401 || status === 403;
147
+ }
148
+ // Check error message directly
149
+ if (error.message) {
150
+ return error.message.includes('unauthorized') ||
151
+ error.message.includes('authentication') ||
152
+ error.message.includes('permission') ||
153
+ error.message.includes('invalid token');
154
+ }
155
+ return false;
156
+ }
157
+ /**
158
+ * Execute a GraphQL mutation
159
+ * @param mutation The GraphQL mutation
160
+ * @param variables Variables for the mutation
161
+ * @returns The mutation response
162
+ */
163
+ async mutate(mutation, variables) {
164
+ try {
165
+ const startTime = process.hrtime.bigint();
166
+ const operationName = mutation.match(/mutation\s+(\w+)?/)?.[1] || 'UnnamedMutation';
167
+ if (this.debug) {
168
+ logger.debug(`🕒 Starting GraphQL mutation: ${operationName}`);
169
+ }
170
+ const result = await this.client.request(mutation, variables);
171
+ // Invalidate relevant caches after mutations
172
+ if (this.cacheManager) {
173
+ // Determine what cache types to invalidate based on mutation name/content
174
+ if (mutation.includes('Pipeline')) {
175
+ await this.cacheManager.invalidateType('pipelines');
176
+ }
177
+ else if (mutation.includes('Build')) {
178
+ await this.cacheManager.invalidateType('builds');
179
+ }
180
+ }
181
+ const endTime = process.hrtime.bigint();
182
+ const duration = Number(endTime - startTime) / 1000000; // Convert to milliseconds
183
+ logger.debug(`✅ GraphQL mutation completed: ${operationName} (${duration.toFixed(2)}ms)`);
184
+ return result;
185
+ }
186
+ catch (error) {
187
+ logger.error('GraphQL mutation error:', error);
188
+ throw error;
189
+ }
190
+ }
191
+ /**
192
+ * Get the organization slugs for the current viewer
193
+ * @returns An array of organization slugs the current user belongs to
194
+ */
195
+ async getViewerOrganizationSlugs() {
196
+ try {
197
+ const startTime = process.hrtime.bigint();
198
+ if (this.debug) {
199
+ logger.debug(`🕒 Starting GraphQL query: getViewerOrganizationSlugs`);
200
+ }
201
+ // Get the organizations using our query
202
+ if (this.debug) {
203
+ logger.debug('About to call this.query with GET_ORGANIZATIONS');
204
+ }
205
+ const data = await this.query(GET_ORGANIZATIONS.toString());
206
+ if (this.debug) {
207
+ logger.debug('Successfully got data from this.query');
208
+ }
209
+ if (this.debug) {
210
+ logger.debug('Raw GraphQL response for organizations:', {
211
+ hasData: !!data,
212
+ hasViewer: !!data?.viewer,
213
+ hasOrganizations: !!data?.viewer?.organizations,
214
+ hasEdges: !!data?.viewer?.organizations?.edges,
215
+ edgesLength: data?.viewer?.organizations?.edges?.length || 0
216
+ });
217
+ }
218
+ // Use our helper method to process the response
219
+ const organizations = this.processOrganizationsResponse(data);
220
+ if (this.debug) {
221
+ logger.debug('Processed organizations:', {
222
+ count: organizations.length,
223
+ organizations: organizations.map(org => ({ id: org.id, name: org.name, slug: org.slug }))
224
+ });
225
+ }
226
+ if (organizations.length === 0) {
227
+ if (this.debug) {
228
+ logger.debug('No organizations found in response', { data });
229
+ }
230
+ return [];
231
+ }
232
+ // Map to just the slugs
233
+ const slugs = organizations.map(org => org.slug);
234
+ const endTime = process.hrtime.bigint();
235
+ const duration = Number(endTime - startTime) / 1000000; // Convert to milliseconds
236
+ if (this.debug) {
237
+ logger.debug(`✅ Found ${slugs.length} organizations (${duration.toFixed(2)}ms)`);
238
+ }
239
+ return slugs;
240
+ }
241
+ catch (error) {
242
+ if (this.debug) {
243
+ logger.debug('GraphQL query failed', {
244
+ error: error instanceof Error ? error.message : String(error),
245
+ details: error instanceof Error ? error : undefined
246
+ });
247
+ // Log more detailed error information
248
+ if (error instanceof Error && 'response' in error) {
249
+ const response = error.response;
250
+ logger.debug('GraphQL error response:', {
251
+ status: response?.status,
252
+ statusText: response?.statusText,
253
+ errors: response?.errors,
254
+ data: response?.data
255
+ });
256
+ }
257
+ // Log detailed error information
258
+ logger.debug('Error in getViewerOrganizationSlugs:', {
259
+ errorMessage: error instanceof Error ? error.message : String(error),
260
+ errorType: error?.constructor?.name,
261
+ hasResponse: error instanceof Error && 'response' in error,
262
+ response: error instanceof Error && 'response' in error ? error.response : undefined
263
+ });
264
+ }
265
+ throw new Error('Failed to determine your organizations', { cause: error });
266
+ }
267
+ }
268
+ /**
269
+ * Clear all cache entries
270
+ */
271
+ async clearCache() {
272
+ if (this.cacheManager) {
273
+ await this.cacheManager.clear();
274
+ }
275
+ }
276
+ /**
277
+ * Invalidate a specific cache type
278
+ */
279
+ async invalidateCache(type) {
280
+ if (this.cacheManager) {
281
+ await this.cacheManager.invalidateType(type);
282
+ }
283
+ }
284
+ /**
285
+ * Get the current viewer information with type safety
286
+ * @returns The viewer data
287
+ */
288
+ async getViewer() {
289
+ if (this.debug) {
290
+ logger.debug(`🕒 Starting GraphQL query: GetViewer`);
291
+ }
292
+ // Check if result is in cache
293
+ if (this.cacheManager) {
294
+ const cachedResult = await this.cacheManager.get(GET_VIEWER.toString(), {});
295
+ if (cachedResult) {
296
+ if (this.debug) {
297
+ logger.debug(`✅ Served from cache: GetViewer`);
298
+ }
299
+ return cachedResult;
300
+ }
301
+ }
302
+ const startTime = process.hrtime.bigint();
303
+ const result = await this.client.request(GET_VIEWER.toString());
304
+ // Store result in cache if caching is enabled
305
+ if (this.cacheManager) {
306
+ await this.cacheManager.set(GET_VIEWER.toString(), result, {});
307
+ }
308
+ const endTime = process.hrtime.bigint();
309
+ const duration = Number(endTime - startTime) / 1000000; // Convert to milliseconds
310
+ if (this.debug) {
311
+ logger.debug(`✅ GraphQL query completed: GetViewer (${duration.toFixed(2)}ms)`);
312
+ }
313
+ return result;
314
+ }
315
+ /**
316
+ * Get organizations for the current viewer
317
+ * @returns An array of organization objects with id, name, and slug
318
+ */
319
+ async getOrganizations() {
320
+ if (this.debug) {
321
+ logger.debug(`🕒 Starting GraphQL query: GetOrganizations`);
322
+ }
323
+ // Check if result is in cache
324
+ if (this.cacheManager) {
325
+ const cachedResult = await this.cacheManager.get(GET_ORGANIZATIONS.toString(), {});
326
+ if (cachedResult) {
327
+ if (this.debug) {
328
+ logger.debug(`✅ Served from cache: GetOrganizations`);
329
+ }
330
+ return this.processOrganizationsResponse(cachedResult);
331
+ }
332
+ }
333
+ const startTime = process.hrtime.bigint();
334
+ const result = await this.client.request(GET_ORGANIZATIONS.toString());
335
+ // Store result in cache if caching is enabled
336
+ if (this.cacheManager) {
337
+ await this.cacheManager.set(GET_ORGANIZATIONS.toString(), result, {});
338
+ }
339
+ const endTime = process.hrtime.bigint();
340
+ const duration = Number(endTime - startTime) / 1000000; // Convert to milliseconds
341
+ if (this.debug) {
342
+ logger.debug(`✅ GraphQL query completed: GetOrganizations (${duration.toFixed(2)}ms)`);
343
+ }
344
+ return this.processOrganizationsResponse(result);
345
+ }
346
+ /**
347
+ * Process the raw GraphQL organizations response into a clean array
348
+ * @param data The raw GraphQL response
349
+ * @returns A processed array of organization objects
350
+ * @private
351
+ */
352
+ processOrganizationsResponse(data) {
353
+ if (!data?.viewer?.organizations?.edges) {
354
+ return [];
355
+ }
356
+ const edges = data.viewer.organizations.edges;
357
+ // Filter out null edges and map to non-null nodes
358
+ const organizations = edges
359
+ .filter((edge) => edge !== null)
360
+ .map(edge => edge.node)
361
+ .filter((node) => node !== null);
362
+ return organizations;
363
+ }
364
+ /**
365
+ * Get pipelines for an organization with type safety
366
+ * @param organizationSlug The organization slug
367
+ * @param first Number of pipelines to retrieve
368
+ * @param after Cursor for pagination
369
+ * @returns The pipelines data
370
+ */
371
+ async getPipelines(organizationSlug, first, after) {
372
+ const variables = {
373
+ organizationSlug,
374
+ first,
375
+ after,
376
+ };
377
+ if (this.debug) {
378
+ logger.debug(`🕒 Starting GraphQL query: GetPipelines for ${organizationSlug}`);
379
+ }
380
+ // Check if result is in cache
381
+ if (this.cacheManager) {
382
+ const cachedResult = await this.cacheManager.get(GET_PIPELINES.toString(), variables);
383
+ if (cachedResult) {
384
+ if (this.debug) {
385
+ logger.debug(`✅ Served from cache: GetPipelines`);
386
+ }
387
+ return cachedResult;
388
+ }
389
+ }
390
+ const startTime = process.hrtime.bigint();
391
+ const result = await this.client.request(GET_PIPELINES.toString(), variables);
392
+ // Store result in cache if caching is enabled
393
+ if (this.cacheManager) {
394
+ await this.cacheManager.set(GET_PIPELINES.toString(), result, variables);
395
+ }
396
+ const endTime = process.hrtime.bigint();
397
+ const duration = Number(endTime - startTime) / 1000000; // Convert to milliseconds
398
+ if (this.debug) {
399
+ logger.debug(`✅ GraphQL query completed: GetPipelines (${duration.toFixed(2)}ms)`);
400
+ }
401
+ return result;
402
+ }
403
+ /**
404
+ * Get builds for a pipeline with type safety
405
+ * @param pipelineSlug The pipeline slug
406
+ * @param organizationSlug The organization slug
407
+ * @param first Number of builds to retrieve
408
+ * @returns The builds data
409
+ */
410
+ async getBuilds(pipelineSlug, organizationSlug, first) {
411
+ const variables = {
412
+ pipelineSlug,
413
+ organizationSlug,
414
+ first,
415
+ };
416
+ if (this.debug) {
417
+ logger.debug(`🕒 Starting GraphQL query: GetBuilds for ${pipelineSlug} in ${organizationSlug}`);
418
+ }
419
+ // Check if result is in cache
420
+ if (this.cacheManager) {
421
+ const cachedResult = await this.cacheManager.get(GET_BUILDS.toString(), variables);
422
+ if (cachedResult) {
423
+ if (this.debug) {
424
+ logger.debug(`✅ Served from cache: GetBuilds`);
425
+ }
426
+ return cachedResult;
427
+ }
428
+ }
429
+ const startTime = process.hrtime.bigint();
430
+ const result = await this.client.request(GET_BUILDS.toString(), variables);
431
+ // Store result in cache if caching is enabled
432
+ if (this.cacheManager) {
433
+ await this.cacheManager.set(GET_BUILDS.toString(), result, variables);
434
+ }
435
+ const endTime = process.hrtime.bigint();
436
+ const duration = Number(endTime - startTime) / 1000000; // Convert to milliseconds
437
+ if (this.debug) {
438
+ logger.debug(`✅ GraphQL query completed: GetBuilds (${duration.toFixed(2)}ms)`);
439
+ }
440
+ return result;
441
+ }
442
+ /**
443
+ * Get builds for the current viewer with type safety
444
+ * @param first Number of builds to retrieve
445
+ * @returns The viewer builds data
446
+ */
447
+ async getViewerBuilds(first) {
448
+ const variables = {
449
+ first,
450
+ };
451
+ if (this.debug) {
452
+ logger.debug(`🕒 Starting GraphQL query: GetViewerBuilds`);
453
+ }
454
+ // Check if result is in cache
455
+ if (this.cacheManager) {
456
+ const cachedResult = await this.cacheManager.get(GET_VIEWER_BUILDS.toString(), variables);
457
+ if (cachedResult) {
458
+ if (this.debug) {
459
+ logger.debug(`✅ Served from cache: GetViewerBuilds`);
460
+ }
461
+ return cachedResult;
462
+ }
463
+ }
464
+ const startTime = process.hrtime.bigint();
465
+ const result = await this.client.request(GET_VIEWER_BUILDS.toString(), variables);
466
+ // Store result in cache if caching is enabled
467
+ if (this.cacheManager) {
468
+ await this.cacheManager.set(GET_VIEWER_BUILDS.toString(), result, variables);
469
+ }
470
+ const endTime = process.hrtime.bigint();
471
+ const duration = Number(endTime - startTime) / 1000000; // Convert to milliseconds
472
+ if (this.debug) {
473
+ logger.debug(`✅ GraphQL query completed: GetViewerBuilds (${duration.toFixed(2)}ms)`);
474
+ }
475
+ return result;
476
+ }
477
+ /**
478
+ * Get the current rate limit information
479
+ * @returns Current rate limit information or null if not available
480
+ */
481
+ getRateLimitInfo() {
482
+ return this.rateLimitInfo;
483
+ }
484
+ /**
485
+ * Get annotations for a build with type safety
486
+ * @param buildSlug The build slug (e.g., "org/pipeline/number")
487
+ * @returns The build annotations data
488
+ */
489
+ async getBuildAnnotations(buildSlug) {
490
+ const variables = {
491
+ buildSlug,
492
+ };
493
+ if (this.debug) {
494
+ logger.debug(`🕒 Starting GraphQL query: GetBuildAnnotations for ${buildSlug}`);
495
+ }
496
+ // Check if result is in cache
497
+ if (this.cacheManager) {
498
+ const cachedResult = await this.cacheManager.get(GET_BUILD_ANNOTATIONS.toString(), variables);
499
+ if (cachedResult) {
500
+ if (this.debug) {
501
+ logger.debug(`✅ Served from cache: GetBuildAnnotations`);
502
+ }
503
+ return cachedResult;
504
+ }
505
+ }
506
+ const startTime = process.hrtime.bigint();
507
+ const result = await this.client.request(GET_BUILD_ANNOTATIONS.toString(), variables);
508
+ // Store result in cache if caching is enabled
509
+ if (this.cacheManager) {
510
+ await this.cacheManager.set(GET_BUILD_ANNOTATIONS.toString(), result, variables);
511
+ }
512
+ const endTime = process.hrtime.bigint();
513
+ const duration = Number(endTime - startTime) / 1000000; // Convert to milliseconds
514
+ if (this.debug) {
515
+ logger.debug(`✅ GraphQL query completed: GetBuildAnnotations (${duration.toFixed(2)}ms)`);
516
+ }
517
+ return result;
518
+ }
519
+ }
520
+ //# sourceMappingURL=BuildkiteClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BuildkiteClient.js","sourceRoot":"/","sources":["services/BuildkiteClient.ts"],"names":[],"mappings":"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","sourcesContent":["import { GraphQLClient } from 'graphql-request';\nimport { CacheManager } from './CacheManager.js';\n// Import the queries - we'll use them for both string queries and typed SDK\nimport { \n GET_VIEWER, \n GET_ORGANIZATIONS, \n GET_PIPELINES, \n GET_BUILDS, \n GET_VIEWER_BUILDS,\n GET_BUILD_ANNOTATIONS\n} from '../graphql/queries.js';\n// Import generated types\nimport { \n GetViewerQuery, \n GetOrganizationsQuery, \n GetPipelinesQuery, \n GetPipelinesQueryVariables,\n GetBuildsQuery,\n GetBuildsQueryVariables,\n GetViewerBuildsQuery,\n GetViewerBuildsQueryVariables,\n} from '../graphql/generated/sdk.js';\nimport { logger } from './logger.js';\n\n// Note: We're now using the automatically generated types from GraphQL Codegen\n\nexport interface BuildkiteClientOptions {\n debug?: boolean;\n baseUrl?: string;\n caching?: boolean;\n cacheTTLs?: Partial<{\n viewer: number;\n organizations: number;\n pipelines: number;\n builds: number;\n default: number;\n }>;\n}\n\nexport interface RateLimitInfo {\n remaining: number;\n limit: number;\n reset: number;\n}\n\n/**\n * BuildkiteClient provides methods to interact with the Buildkite GraphQL API\n */\nexport class BuildkiteClient {\n private client: GraphQLClient;\n private token: string;\n private baseUrl: string = 'https://graphql.buildkite.com/v1';\n private cacheManager: CacheManager | null = null;\n private debug: boolean = false;\n private rateLimitInfo: RateLimitInfo | null = null;\n /**\n * Create a new BuildkiteClient\n * @param token Your Buildkite API token\n * @param options Configuration options\n */\n constructor(token: string, options?: BuildkiteClientOptions, debug?: boolean) {\n this.token = token;\n this.debug = debug || options?.debug || false;\n \n if (this.debug) {\n logger.debug('Initializing BuildkiteClient with options:', {\n baseUrl: options?.baseUrl || this.baseUrl,\n caching: options?.caching !== false,\n debug: this.debug,\n tokenLength: token ? token.length : 0\n });\n }\n \n if (options?.baseUrl) {\n this.baseUrl = options.baseUrl;\n }\n\n this.client = new GraphQLClient(this.baseUrl, {\n headers: {\n Authorization: `Bearer ${this.token}`,\n },\n });\n\n // Initialize cache if caching is enabled\n if (options?.caching !== false) {\n if (this.debug) {\n logger.debug('BuildkiteClient constructor - creating CacheManager');\n }\n this.cacheManager = new CacheManager(options?.cacheTTLs, this.debug);\n // Initialize cache and set token hash (async, but we don't wait)\n this.initCache();\n } else {\n if (this.debug) {\n logger.debug('BuildkiteClient constructor - caching disabled');\n }\n }\n }\n\n /**\n * Initialize cache asynchronously\n */\n private async initCache(): Promise<void> {\n if (this.cacheManager) {\n await this.cacheManager.init();\n await this.cacheManager.setTokenHash(this.token);\n }\n }\n\n /**\n * Execute a GraphQL query\n * @param query The GraphQL query\n * @param variables Variables for the query\n * @returns The query response\n */\n public async query<T = unknown, V extends Record<string, any> = Record<string, any>>(\n query: string,\n variables?: V\n ): Promise<T> {\n try {\n const startTime = process.hrtime.bigint();\n const operationName = query.match(/query\\s+(\\w+)?/)?.[1] || 'UnnamedQuery';\n if (this.debug) {\n logger.debug(`🕒 Starting GraphQL query: ${operationName}`);\n }\n \n // Check if result is in cache\n if (this.cacheManager) {\n if (this.debug) {\n logger.debug('query() - cacheManager exists, checking cache');\n }\n const cachedResult = await this.cacheManager.get<T>(query, variables);\n \n if (cachedResult) {\n if (this.debug) {\n logger.debug(`✅ Served from cache: ${operationName}`);\n }\n return cachedResult;\n }\n }\n \n const response = await this.client.request<T>(query, variables);\n\n // Store result in cache if caching is enabled\n if (this.cacheManager) {\n await this.cacheManager.set(query, response, variables);\n }\n \n const endTime = process.hrtime.bigint();\n const duration = Number(endTime - startTime) / 1000000; // Convert to milliseconds\n if (this.debug) {\n logger.debug(`✅ GraphQL query completed: ${operationName} (${duration.toFixed(2)}ms)`);\n }\n \n return response;\n } catch (error: unknown) {\n const isAuthError = this.isAuthenticationError(error as any);\n if (isAuthError && this.debug) {\n logger.debug('Authentication error detected, not caching result');\n }\n \n if (this.debug) {\n logger.error(error as any, 'Error in GraphQL query');\n // Log raw error information\n logger.debug('Raw error object:', { \n error, \n type: typeof error, \n constructor: (error as any)?.constructor?.name,\n keys: error && typeof error === 'object' ? Object.keys(error as any) : undefined\n });\n // Log more detailed error information\n if (error instanceof Error && 'response' in (error as any)) {\n const response = (error as any).response;\n logger.debug('GraphQL error details:', {\n status: response?.status,\n statusText: response?.statusText,\n errors: response?.errors,\n data: response?.data,\n headers: response?.headers ? Object.fromEntries(response.headers.entries()) : undefined\n });\n }\n }\n throw error;\n }\n }\n\n /**\n * Check if an error is an authentication error\n */\n private isAuthenticationError(error: any): boolean {\n // Check for common authentication error patterns\n if (error.response?.errors) {\n const errors = error.response.errors;\n return errors.some((err: any) => \n err.message?.includes('unauthorized') || \n err.message?.includes('authentication') || \n err.message?.includes('permission') ||\n err.message?.includes('invalid token')\n );\n }\n \n // Check for HTTP status codes that indicate auth issues\n if (error.response?.status) {\n const status = error.response.status;\n return status === 401 || status === 403;\n }\n \n // Check error message directly\n if (error.message) {\n return error.message.includes('unauthorized') || \n error.message.includes('authentication') || \n error.message.includes('permission') ||\n error.message.includes('invalid token');\n }\n \n return false;\n }\n\n /**\n * Execute a GraphQL mutation\n * @param mutation The GraphQL mutation\n * @param variables Variables for the mutation\n * @returns The mutation response\n */\n public async mutate<T = unknown, V extends Record<string, any> = Record<string, any>>(\n mutation: string,\n variables?: V\n ): Promise<T> {\n try {\n const startTime = process.hrtime.bigint();\n const operationName = mutation.match(/mutation\\s+(\\w+)?/)?.[1] || 'UnnamedMutation';\n if (this.debug) {\n logger.debug(`🕒 Starting GraphQL mutation: ${operationName}`);\n }\n \n const result = await this.client.request<T>(mutation, variables);\n \n // Invalidate relevant caches after mutations\n if (this.cacheManager) {\n // Determine what cache types to invalidate based on mutation name/content\n if (mutation.includes('Pipeline')) {\n await this.cacheManager.invalidateType('pipelines');\n } else if (mutation.includes('Build')) {\n await this.cacheManager.invalidateType('builds');\n }\n }\n \n const endTime = process.hrtime.bigint();\n const duration = Number(endTime - startTime) / 1000000; // Convert to milliseconds\n logger.debug(`✅ GraphQL mutation completed: ${operationName} (${duration.toFixed(2)}ms)`);\n \n return result;\n } catch (error) {\n logger.error('GraphQL mutation error:', error);\n throw error;\n }\n }\n\n /**\n * Get the organization slugs for the current viewer\n * @returns An array of organization slugs the current user belongs to\n */\n public async getViewerOrganizationSlugs(): Promise<string[]> {\n try {\n const startTime = process.hrtime.bigint();\n if (this.debug) {\n logger.debug(`🕒 Starting GraphQL query: getViewerOrganizationSlugs`);\n }\n \n // Get the organizations using our query\n if (this.debug) {\n logger.debug('About to call this.query with GET_ORGANIZATIONS');\n }\n const data = await this.query<GetOrganizationsQuery>(GET_ORGANIZATIONS.toString());\n if (this.debug) {\n logger.debug('Successfully got data from this.query');\n }\n \n if (this.debug) {\n logger.debug('Raw GraphQL response for organizations:', {\n hasData: !!data,\n hasViewer: !!data?.viewer,\n hasOrganizations: !!data?.viewer?.organizations,\n hasEdges: !!data?.viewer?.organizations?.edges,\n edgesLength: data?.viewer?.organizations?.edges?.length || 0\n });\n }\n \n // Use our helper method to process the response\n const organizations = this.processOrganizationsResponse(data);\n \n if (this.debug) {\n logger.debug('Processed organizations:', {\n count: organizations.length,\n organizations: organizations.map(org => ({ id: org.id, name: org.name, slug: org.slug }))\n });\n }\n \n if (organizations.length === 0) {\n if (this.debug) {\n logger.debug('No organizations found in response', { data });\n }\n return []\n }\n \n // Map to just the slugs\n const slugs = organizations.map(org => org.slug);\n \n const endTime = process.hrtime.bigint();\n const duration = Number(endTime - startTime) / 1000000; // Convert to milliseconds\n if (this.debug) {\n logger.debug(`✅ Found ${slugs.length} organizations (${duration.toFixed(2)}ms)`);\n }\n \n return slugs;\n } catch (error) {\n if (this.debug) {\n logger.debug('GraphQL query failed', {\n error: error instanceof Error ? error.message : String(error),\n details: error instanceof Error ? error : undefined\n });\n \n // Log more detailed error information\n if (error instanceof Error && 'response' in error) {\n const response = (error as any).response;\n logger.debug('GraphQL error response:', {\n status: response?.status,\n statusText: response?.statusText,\n errors: response?.errors,\n data: response?.data\n });\n }\n \n // Log detailed error information\n logger.debug('Error in getViewerOrganizationSlugs:', {\n errorMessage: error instanceof Error ? error.message : String(error),\n errorType: error?.constructor?.name,\n hasResponse: error instanceof Error && 'response' in error,\n response: error instanceof Error && 'response' in error ? (error as any).response : undefined\n });\n }\n throw new Error('Failed to determine your organizations', { cause: error });\n }\n }\n\n /**\n * Clear all cache entries\n */\n public async clearCache(): Promise<void> {\n if (this.cacheManager) {\n await this.cacheManager.clear();\n }\n }\n\n /**\n * Invalidate a specific cache type\n */\n public async invalidateCache(type: string): Promise<void> {\n if (this.cacheManager) {\n await this.cacheManager.invalidateType(type);\n }\n }\n\n /**\n * Get the current viewer information with type safety\n * @returns The viewer data\n */\n public async getViewer(): Promise<GetViewerQuery> {\n if (this.debug) {\n logger.debug(`🕒 Starting GraphQL query: GetViewer`);\n }\n\n // Check if result is in cache\n if (this.cacheManager) {\n const cachedResult = await this.cacheManager.get<GetViewerQuery>(GET_VIEWER.toString(), {});\n if (cachedResult) {\n if (this.debug) {\n logger.debug(`✅ Served from cache: GetViewer`);\n }\n return cachedResult;\n }\n }\n\n const startTime = process.hrtime.bigint();\n const result = await this.client.request<GetViewerQuery>(GET_VIEWER.toString());\n\n // Store result in cache if caching is enabled\n if (this.cacheManager) {\n await this.cacheManager.set(GET_VIEWER.toString(), result, {});\n }\n\n const endTime = process.hrtime.bigint();\n const duration = Number(endTime - startTime) / 1000000; // Convert to milliseconds\n if (this.debug) {\n logger.debug(`✅ GraphQL query completed: GetViewer (${duration.toFixed(2)}ms)`);\n }\n\n return result;\n }\n\n /**\n * Get organizations for the current viewer\n * @returns An array of organization objects with id, name, and slug\n */\n public async getOrganizations(): Promise<Array<{ id: string; name: string; slug: string; }>> {\n if (this.debug) {\n logger.debug(`🕒 Starting GraphQL query: GetOrganizations`);\n }\n\n // Check if result is in cache\n if (this.cacheManager) {\n const cachedResult = await this.cacheManager.get<GetOrganizationsQuery>(GET_ORGANIZATIONS.toString(), {});\n if (cachedResult) {\n if (this.debug) {\n logger.debug(`✅ Served from cache: GetOrganizations`);\n }\n return this.processOrganizationsResponse(cachedResult);\n }\n }\n\n const startTime = process.hrtime.bigint();\n const result = await this.client.request<GetOrganizationsQuery>(GET_ORGANIZATIONS.toString());\n\n // Store result in cache if caching is enabled\n if (this.cacheManager) {\n await this.cacheManager.set(GET_ORGANIZATIONS.toString(), result, {});\n }\n\n const endTime = process.hrtime.bigint();\n const duration = Number(endTime - startTime) / 1000000; // Convert to milliseconds\n if (this.debug) {\n logger.debug(`✅ GraphQL query completed: GetOrganizations (${duration.toFixed(2)}ms)`);\n }\n\n return this.processOrganizationsResponse(result);\n }\n\n /**\n * Process the raw GraphQL organizations response into a clean array\n * @param data The raw GraphQL response\n * @returns A processed array of organization objects\n * @private\n */\n private processOrganizationsResponse(data: GetOrganizationsQuery): Array<{ id: string; name: string; slug: string; }> {\n if (!data?.viewer?.organizations?.edges) {\n return [];\n }\n \n const edges = data.viewer.organizations.edges;\n \n // Filter out null edges and map to non-null nodes\n const organizations = edges\n .filter((edge): edge is NonNullable<typeof edge> => edge !== null)\n .map(edge => edge.node)\n .filter((node): node is NonNullable<typeof node> => node !== null);\n \n return organizations;\n }\n\n /**\n * Get pipelines for an organization with type safety\n * @param organizationSlug The organization slug\n * @param first Number of pipelines to retrieve\n * @param after Cursor for pagination\n * @returns The pipelines data\n */\n public async getPipelines(\n organizationSlug: string, \n first?: number, \n after?: string\n ): Promise<GetPipelinesQuery> {\n const variables: GetPipelinesQueryVariables = {\n organizationSlug,\n first,\n after,\n };\n\n if (this.debug) {\n logger.debug(`🕒 Starting GraphQL query: GetPipelines for ${organizationSlug}`);\n }\n\n // Check if result is in cache\n if (this.cacheManager) {\n const cachedResult = await this.cacheManager.get<GetPipelinesQuery>(GET_PIPELINES.toString(), variables);\n if (cachedResult) {\n if (this.debug) {\n logger.debug(`✅ Served from cache: GetPipelines`);\n }\n return cachedResult;\n }\n }\n\n const startTime = process.hrtime.bigint();\n const result = await this.client.request<GetPipelinesQuery>(GET_PIPELINES.toString(), variables);\n\n // Store result in cache if caching is enabled\n if (this.cacheManager) {\n await this.cacheManager.set(GET_PIPELINES.toString(), result, variables);\n }\n\n const endTime = process.hrtime.bigint();\n const duration = Number(endTime - startTime) / 1000000; // Convert to milliseconds\n if (this.debug) {\n logger.debug(`✅ GraphQL query completed: GetPipelines (${duration.toFixed(2)}ms)`);\n }\n\n return result;\n }\n\n /**\n * Get builds for a pipeline with type safety\n * @param pipelineSlug The pipeline slug\n * @param organizationSlug The organization slug\n * @param first Number of builds to retrieve\n * @returns The builds data\n */\n public async getBuilds(\n pipelineSlug: string,\n organizationSlug: string,\n first?: number\n ): Promise<GetBuildsQuery> {\n const variables: GetBuildsQueryVariables = {\n pipelineSlug,\n organizationSlug,\n first,\n };\n\n if (this.debug) {\n logger.debug(`🕒 Starting GraphQL query: GetBuilds for ${pipelineSlug} in ${organizationSlug}`);\n }\n\n // Check if result is in cache\n if (this.cacheManager) {\n const cachedResult = await this.cacheManager.get<GetBuildsQuery>(GET_BUILDS.toString(), variables);\n if (cachedResult) {\n if (this.debug) {\n logger.debug(`✅ Served from cache: GetBuilds`);\n }\n return cachedResult;\n }\n }\n\n const startTime = process.hrtime.bigint();\n const result = await this.client.request<GetBuildsQuery>(GET_BUILDS.toString(), variables);\n\n // Store result in cache if caching is enabled\n if (this.cacheManager) {\n await this.cacheManager.set(GET_BUILDS.toString(), result, variables);\n }\n\n const endTime = process.hrtime.bigint();\n const duration = Number(endTime - startTime) / 1000000; // Convert to milliseconds\n if (this.debug) {\n logger.debug(`✅ GraphQL query completed: GetBuilds (${duration.toFixed(2)}ms)`);\n }\n\n return result;\n }\n\n /**\n * Get builds for the current viewer with type safety\n * @param first Number of builds to retrieve\n * @returns The viewer builds data\n */\n public async getViewerBuilds(first: number): Promise<GetViewerBuildsQuery> {\n const variables: GetViewerBuildsQueryVariables = {\n first,\n };\n\n if (this.debug) {\n logger.debug(`🕒 Starting GraphQL query: GetViewerBuilds`);\n }\n\n // Check if result is in cache\n if (this.cacheManager) {\n const cachedResult = await this.cacheManager.get<GetViewerBuildsQuery>(GET_VIEWER_BUILDS.toString(), variables);\n if (cachedResult) {\n if (this.debug) {\n logger.debug(`✅ Served from cache: GetViewerBuilds`);\n }\n return cachedResult;\n }\n }\n\n const startTime = process.hrtime.bigint();\n const result = await this.client.request<GetViewerBuildsQuery>(GET_VIEWER_BUILDS.toString(), variables);\n\n // Store result in cache if caching is enabled\n if (this.cacheManager) {\n await this.cacheManager.set(GET_VIEWER_BUILDS.toString(), result, variables);\n }\n\n const endTime = process.hrtime.bigint();\n const duration = Number(endTime - startTime) / 1000000; // Convert to milliseconds\n if (this.debug) {\n logger.debug(`✅ GraphQL query completed: GetViewerBuilds (${duration.toFixed(2)}ms)`);\n }\n\n return result;\n }\n\n /**\n * Get the current rate limit information\n * @returns Current rate limit information or null if not available\n */\n public getRateLimitInfo(): RateLimitInfo | null {\n return this.rateLimitInfo;\n }\n\n /**\n * Get annotations for a build with type safety\n * @param buildSlug The build slug (e.g., \"org/pipeline/number\")\n * @returns The build annotations data\n */\n public async getBuildAnnotations(buildSlug: string): Promise<any> {\n const variables = {\n buildSlug,\n };\n\n if (this.debug) {\n logger.debug(`🕒 Starting GraphQL query: GetBuildAnnotations for ${buildSlug}`);\n }\n\n // Check if result is in cache\n if (this.cacheManager) {\n const cachedResult = await this.cacheManager.get<any>(GET_BUILD_ANNOTATIONS.toString(), variables);\n if (cachedResult) {\n if (this.debug) {\n logger.debug(`✅ Served from cache: GetBuildAnnotations`);\n }\n return cachedResult;\n }\n }\n\n const startTime = process.hrtime.bigint();\n const result = await this.client.request<any>(GET_BUILD_ANNOTATIONS.toString(), variables);\n\n // Store result in cache if caching is enabled\n if (this.cacheManager) {\n await this.cacheManager.set(GET_BUILD_ANNOTATIONS.toString(), result, variables);\n }\n\n const endTime = process.hrtime.bigint();\n const duration = Number(endTime - startTime) / 1000000; // Convert to milliseconds\n if (this.debug) {\n logger.debug(`✅ GraphQL query completed: GetBuildAnnotations (${duration.toFixed(2)}ms)`);\n }\n\n return result;\n }\n}"]}