@@ -36,7 +36,112 @@ import {
3636import { APIPromise } from '../../core/api-promise' ;
3737import { RequestOptions } from '../../internal/request-options' ;
3838import { path } from '../../internal/utils/path' ;
39- import { waitForDatabase } from './wait-for-database' ;
39+ import { GradientError } from '../../core/error' ;
40+ import { sleep } from '../../internal/utils/sleep' ;
41+
42+ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
43+
44+ export interface WaitForDatabaseOptions extends RequestOptions {
45+ /**
46+ * The polling interval in milliseconds. Defaults to 5000 (5 seconds).
47+ */
48+ interval ?: number ;
49+ }
50+
51+ /**
52+ * Database status values that indicate a successful deployment.
53+ */
54+ const ONLINE_STATUSES = [ 'ONLINE' ] as const ;
55+
56+ /**
57+ * Database status values that indicate a failed deployment.
58+ */
59+ const FAILED_STATUSES = [ 'DECOMMISSIONED' , 'UNHEALTHY' ] as const ;
60+
61+ /**
62+ * Database status values that indicate the deployment is still in progress.
63+ */
64+ const PENDING_STATUSES = [
65+ 'CREATING' ,
66+ 'POWEROFF' ,
67+ 'REBUILDING' ,
68+ 'REBALANCING' ,
69+ 'FORKING' ,
70+ 'MIGRATING' ,
71+ 'RESIZING' ,
72+ 'RESTORING' ,
73+ 'POWERING_ON' ,
74+ ] as const ;
75+
76+ export class WaitForDatabaseTimeoutError extends GradientError {
77+ constructor ( message : string , kbId ?: string , timeout ?: number ) {
78+ super ( message ) ;
79+ this . name = 'WaitForDatabaseTimeoutError' ;
80+ if ( kbId ) {
81+ ( this as any ) . knowledgeBaseId = kbId ;
82+ ( this as any ) . timeout = timeout ;
83+ }
84+ }
85+ }
86+
87+ export class WaitForDatabaseFailedError extends GradientError {
88+ constructor ( message : string , kbId ?: string , status ?: string ) {
89+ super ( message ) ;
90+ this . name = 'WaitForDatabaseFailedError' ;
91+ if ( kbId ) {
92+ ( this as any ) . knowledgeBaseId = kbId ;
93+ ( this as any ) . databaseStatus = status ;
94+ }
95+ }
96+ }
97+
98+ /**
99+ * Polls for knowledge base database creation to complete.
100+ *
101+ * This helper function polls the knowledge base status until the database is ONLINE,
102+ * handling various error states and providing configurable timeout and polling intervals.
103+ *
104+ * @example
105+ * ```ts
106+ * import Gradient from '@digitalocean/gradient';
107+ *
108+ * const client = new Gradient();
109+ *
110+ * // Basic usage
111+ * try {
112+ * const kb = await client.knowledgeBases.waitForDatabase('123e4567-e89b-12d3-a456-426614174000');
113+ * console.log('Database is ready:', kb.database_status); // 'ONLINE'
114+ * } catch (error) {
115+ * if (error instanceof WaitForDatabaseTimeoutError) {
116+ * console.log('Polling timed out');
117+ * } else if (error instanceof WaitForDatabaseFailedError) {
118+ * console.log('Database deployment failed');
119+ * }
120+ * }
121+ *
122+ * // With AbortSignal
123+ * const controller = new AbortController();
124+ * setTimeout(() => controller.abort(), 30000); // Cancel after 30 seconds
125+ *
126+ * try {
127+ * const kb = await client.knowledgeBases.waitForDatabase('123e4567-e89b-12d3-a456-426614174000', {
128+ * signal: controller.signal
129+ * });
130+ * } catch (error) {
131+ * if (error.message === 'Operation was aborted') {
132+ * console.log('Operation was cancelled');
133+ * }
134+ * }
135+ * ```
136+ *
137+ * @param client - The Gradient client instance
138+ * @param uuid - The knowledge base UUID to poll for
139+ * @param options - Configuration options for polling behavior
140+ * @returns Promise<KnowledgeBaseRetrieveResponse> - The knowledge base with ONLINE database status
141+ * @throws WaitForDatabaseTimeoutError - If polling times out
142+ * @throws WaitForDatabaseFailedError - If the database enters a failed state
143+ * @throws Error - If the operation is aborted via AbortSignal
144+ */
40145
41146export class KnowledgeBases extends APIResource {
42147 dataSources : DataSourcesAPI . DataSources = new DataSourcesAPI . DataSources ( this . _client ) ;
@@ -159,9 +264,75 @@ export class KnowledgeBases extends APIResource {
159264 */
160265 async waitForDatabase (
161266 uuid : string ,
162- options ?: import ( './wait-for-database' ) . WaitForDatabaseOptions ,
267+ options : WaitForDatabaseOptions = { } ,
163268 ) : Promise < KnowledgeBaseRetrieveResponse > {
164- return waitForDatabase ( this . _client , uuid , options || { } ) ;
269+ const { interval = 5000 , timeout = 600000 , signal } = options ;
270+
271+ const startTime = Date . now ( ) ;
272+
273+ while ( true ) {
274+ // Check if operation was aborted
275+ if ( signal ?. aborted ) {
276+ throw new Error ( 'Operation was aborted' ) ;
277+ }
278+
279+ const elapsed = Date . now ( ) - startTime ;
280+
281+ if ( elapsed > timeout ) {
282+ throw new WaitForDatabaseTimeoutError (
283+ `Knowledge base database ${ uuid } did not become ONLINE within ${ timeout } ms` ,
284+ uuid ,
285+ timeout ,
286+ ) ;
287+ }
288+
289+ try {
290+ const response = await this . retrieve ( uuid , options ) ;
291+ const status = response . database_status ;
292+
293+ if ( ! status ) {
294+ // If database_status is not present, continue polling
295+ await sleep ( interval ) ;
296+ continue ;
297+ }
298+
299+ // Check for successful completion
300+ if ( ONLINE_STATUSES . includes ( status as any ) ) {
301+ return response ;
302+ }
303+
304+ // Check for failed states
305+ if ( FAILED_STATUSES . includes ( status as any ) ) {
306+ throw new WaitForDatabaseFailedError (
307+ `Knowledge base database ${ uuid } entered failed state: ${ status } ` ,
308+ uuid ,
309+ status ,
310+ ) ;
311+ }
312+
313+ // Check if still in progress
314+ if ( PENDING_STATUSES . includes ( status as any ) ) {
315+ await sleep ( interval ) ;
316+ continue ;
317+ }
318+
319+ // Unknown status - treat as error for safety
320+ throw new WaitForDatabaseFailedError (
321+ `Knowledge base database ${ uuid } entered unknown state: ${ status } ` ,
322+ uuid ,
323+ status ,
324+ ) ;
325+ } catch ( error ) {
326+ // If it's our custom error, re-throw it
327+ if ( error instanceof WaitForDatabaseFailedError || error instanceof WaitForDatabaseTimeoutError ) {
328+ throw error ;
329+ }
330+
331+ // For other errors (network issues, etc.), try waiting a bit longer before retrying
332+ await sleep ( Math . min ( interval * 2 , 30000 ) ) ; // Max 30 seconds between retries
333+ continue ;
334+ }
335+ }
165336 }
166337}
167338
@@ -450,13 +621,6 @@ export interface KnowledgeBaseListParams {
450621KnowledgeBases . DataSources = DataSources ;
451622KnowledgeBases . IndexingJobs = IndexingJobs ;
452623
453- export {
454- waitForDatabase ,
455- WaitForDatabaseOptions ,
456- WaitForDatabaseTimeoutError ,
457- WaitForDatabaseFailedError ,
458- } from './wait-for-database' ;
459-
460624export declare namespace KnowledgeBases {
461625 export {
462626 type APIKnowledgeBase as APIKnowledgeBase ,
0 commit comments