@tinybirdco/sdk 0.0.80 → 0.0.81
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/deploy.d.ts +14 -4
- package/dist/api/deploy.d.ts.map +1 -1
- package/dist/api/deploy.js +104 -100
- package/dist/api/deploy.js.map +1 -1
- package/dist/api/deploy.test.js +165 -76
- package/dist/api/deploy.test.js.map +1 -1
- package/dist/cli/commands/deploy.d.ts +8 -0
- package/dist/cli/commands/deploy.d.ts.map +1 -1
- package/dist/cli/commands/deploy.js +2 -0
- package/dist/cli/commands/deploy.js.map +1 -1
- package/dist/cli/index.js +11 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/output.d.ts +15 -0
- package/dist/cli/output.d.ts.map +1 -1
- package/dist/cli/output.js +24 -0
- package/dist/cli/output.js.map +1 -1
- package/dist/test/handlers.d.ts +2 -6
- package/dist/test/handlers.d.ts.map +1 -1
- package/dist/test/handlers.js +5 -9
- package/dist/test/handlers.js.map +1 -1
- package/package.json +1 -1
- package/src/api/deploy.test.ts +193 -100
- package/src/api/deploy.ts +129 -116
- package/src/cli/commands/deploy.ts +10 -0
- package/src/cli/index.ts +18 -0
- package/src/cli/output.ts +27 -0
- package/src/test/handlers.ts +6 -10
package/src/api/deploy.ts
CHANGED
|
@@ -10,6 +10,19 @@ import { tinybirdFetch } from "./fetcher.js";
|
|
|
10
10
|
const FORWARD_CLASSIC_GUIDANCE =
|
|
11
11
|
"Use the Tinybird Classic CLI (`tb`) from a Tinybird Classic workspace for this operation.";
|
|
12
12
|
|
|
13
|
+
/**
|
|
14
|
+
* Poll interval used while waiting for a deployment to reach `data_ready`
|
|
15
|
+
* (and, when auto-promoting, `live`). Matches the Tinybird CLI (`tb deploy`).
|
|
16
|
+
*/
|
|
17
|
+
const POLL_INTERVAL_MS = 5_000;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* How many consecutive `failed` status polls to tolerate before giving up.
|
|
21
|
+
* With a 5s poll interval this is ~5 minutes, matching the CLI safety valve
|
|
22
|
+
* for deployments that fail but never auto-delete.
|
|
23
|
+
*/
|
|
24
|
+
export const MAX_CONSECUTIVE_FAILED_POLLS = 60;
|
|
25
|
+
|
|
13
26
|
/**
|
|
14
27
|
* Feedback item from deployment response
|
|
15
28
|
*/
|
|
@@ -87,8 +100,10 @@ export interface DeploymentStatusResponse {
|
|
|
87
100
|
*
|
|
88
101
|
* Uses the /v1/deploy endpoint which accepts all resources in a single
|
|
89
102
|
* multipart form request. After creating the deployment, this function:
|
|
90
|
-
* 1.
|
|
91
|
-
*
|
|
103
|
+
* 1. When `auto` is true (default), sends `auto_promote=true` so the
|
|
104
|
+
* server promotes the deployment as soon as it's ready.
|
|
105
|
+
* 2. When `wait` is true (default), polls until the deployment reaches
|
|
106
|
+
* `data_ready` (and, if `auto` is also true, until it becomes live).
|
|
92
107
|
*
|
|
93
108
|
* @param config - Build configuration with API URL and token
|
|
94
109
|
* @param resources - Generated resources to deploy
|
|
@@ -139,6 +154,8 @@ export interface DeploymentChanges {
|
|
|
139
154
|
export interface DeployCallbacks {
|
|
140
155
|
/** Called when deployment is created and changes are available */
|
|
141
156
|
onChanges?: (changes: DeploymentChanges) => void;
|
|
157
|
+
/** Called when deployment was submitted but wait was disabled */
|
|
158
|
+
onDeploymentSubmitted?: (deploymentId: string) => void;
|
|
142
159
|
/** Called when waiting for deployment to be ready */
|
|
143
160
|
onWaitingForReady?: () => void;
|
|
144
161
|
/** Called when deployment is ready */
|
|
@@ -158,18 +175,17 @@ export async function deployToMain(
|
|
|
158
175
|
resources: GeneratedResources,
|
|
159
176
|
options?: {
|
|
160
177
|
debug?: boolean;
|
|
161
|
-
pollIntervalMs?: number;
|
|
162
|
-
maxPollAttempts?: number;
|
|
163
178
|
check?: boolean;
|
|
164
179
|
allowDestructiveOperations?: boolean;
|
|
180
|
+
wait?: boolean;
|
|
181
|
+
auto?: boolean;
|
|
165
182
|
callbacks?: DeployCallbacks;
|
|
166
183
|
}
|
|
167
184
|
): Promise<BuildApiResult> {
|
|
168
185
|
const debug = options?.debug ?? !!process.env.TINYBIRD_DEBUG;
|
|
169
|
-
const
|
|
170
|
-
const
|
|
186
|
+
const wait = options?.wait ?? true;
|
|
187
|
+
const auto = options?.auto ?? true;
|
|
171
188
|
const baseUrl = config.baseUrl.replace(/\/$/, "");
|
|
172
|
-
let previousLiveDeploymentId: string | undefined;
|
|
173
189
|
|
|
174
190
|
const formData = new FormData();
|
|
175
191
|
|
|
@@ -231,10 +247,6 @@ export async function deployToMain(
|
|
|
231
247
|
|
|
232
248
|
if (deploymentsResponse.ok) {
|
|
233
249
|
const deploymentsBody = (await deploymentsResponse.json()) as DeploymentsListResponse;
|
|
234
|
-
const previousLiveDeployment = deploymentsBody.deployments.find(
|
|
235
|
-
(d) => d.live || d.status === "live"
|
|
236
|
-
);
|
|
237
|
-
previousLiveDeploymentId = previousLiveDeployment?.id;
|
|
238
250
|
const staleDeployments = deploymentsBody.deployments.filter(
|
|
239
251
|
(d) => !d.live && d.status !== "live"
|
|
240
252
|
);
|
|
@@ -264,6 +276,9 @@ export async function deployToMain(
|
|
|
264
276
|
const urlParams = new URLSearchParams();
|
|
265
277
|
if (options?.check) {
|
|
266
278
|
urlParams.set("check", "true");
|
|
279
|
+
} else if (auto) {
|
|
280
|
+
// Server will auto-promote the deployment when it's ready
|
|
281
|
+
urlParams.set("auto_promote", "true");
|
|
267
282
|
}
|
|
268
283
|
if (options?.allowDestructiveOperations) {
|
|
269
284
|
urlParams.set("allow_destructive_operations", "true");
|
|
@@ -431,18 +446,67 @@ export async function deployToMain(
|
|
|
431
446
|
});
|
|
432
447
|
}
|
|
433
448
|
|
|
434
|
-
|
|
449
|
+
const deploymentChanges = {
|
|
450
|
+
pipes: {
|
|
451
|
+
changed: deploymentDetails.changed_pipe_names ?? [],
|
|
452
|
+
created: deploymentDetails.new_pipe_names ?? [],
|
|
453
|
+
deleted: deploymentDetails.deleted_pipe_names ?? [],
|
|
454
|
+
},
|
|
455
|
+
datasources: {
|
|
456
|
+
changed: deploymentDetails.changed_datasource_names ?? [],
|
|
457
|
+
created: deploymentDetails.new_datasource_names ?? [],
|
|
458
|
+
deleted: deploymentDetails.deleted_datasource_names ?? [],
|
|
459
|
+
},
|
|
460
|
+
};
|
|
461
|
+
|
|
462
|
+
// If we're not waiting, return as soon as the server accepted the deployment.
|
|
463
|
+
if (!wait) {
|
|
464
|
+
options?.callbacks?.onDeploymentSubmitted?.(deploymentId);
|
|
465
|
+
return {
|
|
466
|
+
success: true,
|
|
467
|
+
result: "success",
|
|
468
|
+
datasourceCount: resources.datasources.length,
|
|
469
|
+
pipeCount: resources.pipes.length,
|
|
470
|
+
connectionCount: resources.connections?.length ?? 0,
|
|
471
|
+
buildId: deploymentId,
|
|
472
|
+
...deploymentChanges,
|
|
473
|
+
};
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
// Step 2: Poll until the deployment reaches a terminal state.
|
|
435
477
|
let deployment = body.deployment;
|
|
436
|
-
let
|
|
478
|
+
let timesSeenFailed = 0;
|
|
479
|
+
let notifiedReady = false;
|
|
480
|
+
let notifiedWaitingForPromote = false;
|
|
437
481
|
|
|
438
482
|
options?.callbacks?.onWaitingForReady?.();
|
|
439
483
|
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
484
|
+
const isDone = (): boolean => {
|
|
485
|
+
if (deployment.status !== "data_ready") {
|
|
486
|
+
return false;
|
|
487
|
+
}
|
|
488
|
+
if (auto) {
|
|
489
|
+
// When auto-promoting we must also wait for the server to flip it live.
|
|
490
|
+
return deployment.live === true;
|
|
491
|
+
}
|
|
492
|
+
return true;
|
|
493
|
+
};
|
|
494
|
+
|
|
495
|
+
const buildError = (message: string): BuildApiResult => ({
|
|
496
|
+
success: false,
|
|
497
|
+
result: "failed",
|
|
498
|
+
error: message,
|
|
499
|
+
datasourceCount: resources.datasources.length,
|
|
500
|
+
pipeCount: resources.pipes.length,
|
|
501
|
+
connectionCount: resources.connections?.length ?? 0,
|
|
502
|
+
buildId: deploymentId,
|
|
503
|
+
});
|
|
504
|
+
|
|
505
|
+
while (!isDone()) {
|
|
506
|
+
await sleep(POLL_INTERVAL_MS);
|
|
443
507
|
|
|
444
508
|
if (debug) {
|
|
445
|
-
console.log(`[debug] Polling deployment status
|
|
509
|
+
console.log(`[debug] Polling deployment status...`);
|
|
446
510
|
}
|
|
447
511
|
|
|
448
512
|
const statusUrl = `${baseUrl}/v1/deployments/${deploymentId}`;
|
|
@@ -453,114 +517,72 @@ export async function deployToMain(
|
|
|
453
517
|
});
|
|
454
518
|
|
|
455
519
|
if (!statusResponse.ok) {
|
|
456
|
-
return
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
error: `Failed to check deployment status: ${statusResponse.status} ${statusResponse.statusText}`,
|
|
460
|
-
datasourceCount: resources.datasources.length,
|
|
461
|
-
pipeCount: resources.pipes.length,
|
|
462
|
-
connectionCount: resources.connections?.length ?? 0,
|
|
463
|
-
buildId: deploymentId,
|
|
464
|
-
};
|
|
520
|
+
return buildError(
|
|
521
|
+
`Failed to check deployment status: ${statusResponse.status} ${statusResponse.statusText}`
|
|
522
|
+
);
|
|
465
523
|
}
|
|
466
524
|
|
|
467
525
|
const statusBody = (await statusResponse.json()) as DeploymentStatusResponse;
|
|
468
526
|
deployment = statusBody.deployment;
|
|
469
527
|
|
|
470
528
|
if (debug) {
|
|
471
|
-
console.log(
|
|
529
|
+
console.log(
|
|
530
|
+
`[debug] Deployment status: ${deployment.status} (live=${deployment.live ?? false})`
|
|
531
|
+
);
|
|
472
532
|
}
|
|
473
533
|
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
buildId: deploymentId,
|
|
484
|
-
};
|
|
534
|
+
if (deployment.status === "failed") {
|
|
535
|
+
timesSeenFailed++;
|
|
536
|
+
if (timesSeenFailed > MAX_CONSECUTIVE_FAILED_POLLS) {
|
|
537
|
+
return buildError(
|
|
538
|
+
"Deployment failed to create and didn't start deleting automatically after 5 minutes. " +
|
|
539
|
+
"You might need to delete it manually in the UI."
|
|
540
|
+
);
|
|
541
|
+
}
|
|
542
|
+
continue;
|
|
485
543
|
}
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
if (deployment.status !== "data_ready") {
|
|
489
|
-
return {
|
|
490
|
-
success: false,
|
|
491
|
-
result: "failed",
|
|
492
|
-
error: `Deployment timed out after ${maxPollAttempts} attempts. Last status: ${deployment.status}`,
|
|
493
|
-
datasourceCount: resources.datasources.length,
|
|
494
|
-
pipeCount: resources.pipes.length,
|
|
495
|
-
connectionCount: resources.connections?.length ?? 0,
|
|
496
|
-
buildId: deploymentId,
|
|
497
|
-
};
|
|
498
|
-
}
|
|
499
544
|
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
Authorization: `Bearer ${config.token}`,
|
|
513
|
-
},
|
|
514
|
-
});
|
|
545
|
+
if (deployment.status === "deleting" || deployment.status === "deleted") {
|
|
546
|
+
const errors = deployment.feedback
|
|
547
|
+
?.filter((f) => f.level === "ERROR")
|
|
548
|
+
.map((f) => f.message)
|
|
549
|
+
.join("\n");
|
|
550
|
+
const errorSuffix = errors ? `\n${errors}` : "";
|
|
551
|
+
return buildError(
|
|
552
|
+
`Deployment failed and ${
|
|
553
|
+
deployment.status === "deleting" ? "is being" : "was"
|
|
554
|
+
} deleted automatically.${errorSuffix}`
|
|
555
|
+
);
|
|
556
|
+
}
|
|
515
557
|
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
558
|
+
if (
|
|
559
|
+
auto &&
|
|
560
|
+
deployment.status === "data_ready" &&
|
|
561
|
+
!deployment.live &&
|
|
562
|
+
!notifiedWaitingForPromote
|
|
563
|
+
) {
|
|
564
|
+
if (!notifiedReady) {
|
|
565
|
+
options?.callbacks?.onDeploymentReady?.();
|
|
566
|
+
notifiedReady = true;
|
|
567
|
+
}
|
|
568
|
+
options?.callbacks?.onWaitingForPromote?.();
|
|
569
|
+
notifiedWaitingForPromote = true;
|
|
570
|
+
}
|
|
527
571
|
}
|
|
528
572
|
|
|
529
|
-
if (
|
|
530
|
-
|
|
573
|
+
if (!notifiedReady) {
|
|
574
|
+
options?.callbacks?.onDeploymentReady?.();
|
|
575
|
+
notifiedReady = true;
|
|
531
576
|
}
|
|
532
577
|
|
|
533
|
-
if (
|
|
578
|
+
if (auto) {
|
|
534
579
|
if (debug) {
|
|
535
|
-
console.log(`[debug]
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
const deletePreviousResponse = await tinybirdFetch(
|
|
539
|
-
`${baseUrl}/v1/deployments/${previousLiveDeploymentId}`,
|
|
540
|
-
{
|
|
541
|
-
method: "DELETE",
|
|
542
|
-
headers: {
|
|
543
|
-
Authorization: `Bearer ${config.token}`,
|
|
544
|
-
},
|
|
545
|
-
}
|
|
546
|
-
);
|
|
547
|
-
|
|
548
|
-
if (!deletePreviousResponse.ok) {
|
|
549
|
-
const deletePreviousBody = await deletePreviousResponse.text();
|
|
550
|
-
return {
|
|
551
|
-
success: false,
|
|
552
|
-
result: "failed",
|
|
553
|
-
error: `Failed to remove previous deployment: ${deletePreviousResponse.status} ${deletePreviousResponse.statusText}\n${deletePreviousBody}`,
|
|
554
|
-
datasourceCount: resources.datasources.length,
|
|
555
|
-
pipeCount: resources.pipes.length,
|
|
556
|
-
connectionCount: resources.connections?.length ?? 0,
|
|
557
|
-
buildId: deploymentId,
|
|
558
|
-
};
|
|
580
|
+
console.log(`[debug] Deployment ${deploymentId} is now live`);
|
|
559
581
|
}
|
|
582
|
+
options?.callbacks?.onDeploymentPromoted?.();
|
|
583
|
+
options?.callbacks?.onDeploymentLive?.(deploymentId);
|
|
560
584
|
}
|
|
561
585
|
|
|
562
|
-
options?.callbacks?.onDeploymentLive?.(deploymentId);
|
|
563
|
-
|
|
564
586
|
return {
|
|
565
587
|
success: true,
|
|
566
588
|
result: "success",
|
|
@@ -568,16 +590,7 @@ export async function deployToMain(
|
|
|
568
590
|
pipeCount: resources.pipes.length,
|
|
569
591
|
connectionCount: resources.connections?.length ?? 0,
|
|
570
592
|
buildId: deploymentId,
|
|
571
|
-
|
|
572
|
-
changed: deploymentDetails.changed_pipe_names ?? [],
|
|
573
|
-
created: deploymentDetails.new_pipe_names ?? [],
|
|
574
|
-
deleted: deploymentDetails.deleted_pipe_names ?? [],
|
|
575
|
-
},
|
|
576
|
-
datasources: {
|
|
577
|
-
changed: deploymentDetails.changed_datasource_names ?? [],
|
|
578
|
-
created: deploymentDetails.new_datasource_names ?? [],
|
|
579
|
-
deleted: deploymentDetails.deleted_datasource_names ?? [],
|
|
580
|
-
},
|
|
593
|
+
...deploymentChanges,
|
|
581
594
|
};
|
|
582
595
|
}
|
|
583
596
|
|
|
@@ -19,6 +19,14 @@ export interface DeployCommandOptions {
|
|
|
19
19
|
check?: boolean;
|
|
20
20
|
/** Allow deleting existing resources in main workspace deploys */
|
|
21
21
|
allowDestructiveOperations?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Wait for the deployment to finish. Defaults to true.
|
|
24
|
+
*/
|
|
25
|
+
wait?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Auto-promote the deployment when it's ready. Defaults to true.
|
|
28
|
+
*/
|
|
29
|
+
auto?: boolean;
|
|
22
30
|
/** Callbacks for deploy progress */
|
|
23
31
|
callbacks?: DeployCallbacks;
|
|
24
32
|
}
|
|
@@ -106,6 +114,8 @@ export async function runDeploy(options: DeployCommandOptions = {}): Promise<Dep
|
|
|
106
114
|
{
|
|
107
115
|
check: options.check,
|
|
108
116
|
allowDestructiveOperations: options.allowDestructiveOperations,
|
|
117
|
+
wait: options.wait,
|
|
118
|
+
auto: options.auto,
|
|
109
119
|
callbacks: options.callbacks,
|
|
110
120
|
}
|
|
111
121
|
);
|
package/src/cli/index.ts
CHANGED
|
@@ -482,18 +482,33 @@ function createCli(): Command {
|
|
|
482
482
|
"--allow-destructive-operations",
|
|
483
483
|
"Allow deploys that delete existing datasources, pipes, or connections"
|
|
484
484
|
)
|
|
485
|
+
.option("--wait", "Wait for the deployment to finish (default)")
|
|
486
|
+
.option("--no-wait", "Return as soon as the deployment is submitted")
|
|
487
|
+
.option(
|
|
488
|
+
"--auto",
|
|
489
|
+
"Auto-promote the deployment when it's ready (default)"
|
|
490
|
+
)
|
|
491
|
+
.option(
|
|
492
|
+
"--no-auto",
|
|
493
|
+
"Do not auto-promote the deployment; leave it staged for a manual promote"
|
|
494
|
+
)
|
|
485
495
|
.option("--debug", "Show debug output including API requests/responses")
|
|
486
496
|
.action(async (options) => {
|
|
487
497
|
if (options.debug) {
|
|
488
498
|
process.env.TINYBIRD_DEBUG = "1";
|
|
489
499
|
}
|
|
490
500
|
|
|
501
|
+
const wait = options.wait !== false;
|
|
502
|
+
const auto = options.auto !== false;
|
|
503
|
+
|
|
491
504
|
output.highlight("Deploying to main workspace...");
|
|
492
505
|
|
|
493
506
|
const result = await runDeploy({
|
|
494
507
|
dryRun: options.dryRun,
|
|
495
508
|
check: options.check,
|
|
496
509
|
allowDestructiveOperations: options.allowDestructiveOperations,
|
|
510
|
+
wait,
|
|
511
|
+
auto,
|
|
497
512
|
callbacks: {
|
|
498
513
|
onChanges: (deployChanges) => {
|
|
499
514
|
// Show changes table immediately after deployment is created
|
|
@@ -531,8 +546,11 @@ function createCli(): Command {
|
|
|
531
546
|
|
|
532
547
|
output.showChangesTable(changes);
|
|
533
548
|
},
|
|
549
|
+
onDeploymentSubmitted: (id) => output.showDeploymentSubmitted(id, auto),
|
|
534
550
|
onWaitingForReady: () => output.showWaitingForDeployment(),
|
|
535
551
|
onDeploymentReady: () => output.showDeploymentReady(),
|
|
552
|
+
onWaitingForPromote: () => output.showWaitingForPromote(),
|
|
553
|
+
onDeploymentPromoted: () => output.showDeploymentPromoted(),
|
|
536
554
|
onDeploymentLive: (id) => output.showDeploymentLive(id),
|
|
537
555
|
onValidating: () => output.showValidatingDeployment(),
|
|
538
556
|
},
|
package/src/cli/output.ts
CHANGED
|
@@ -218,6 +218,30 @@ export function showDeploymentLive(deploymentId: string): void {
|
|
|
218
218
|
success(`✓ Deployment #${deploymentId} is live!`);
|
|
219
219
|
}
|
|
220
220
|
|
|
221
|
+
/**
|
|
222
|
+
* Show waiting for deployment promotion message
|
|
223
|
+
*/
|
|
224
|
+
export function showWaitingForPromote(): void {
|
|
225
|
+
info("» Waiting for deployment to be promoted...");
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Show deployment submitted message (used when --no-wait is set)
|
|
230
|
+
*/
|
|
231
|
+
export function showDeploymentSubmitted(deploymentId: string, autoPromote: boolean): void {
|
|
232
|
+
const autoFrag = autoPromote
|
|
233
|
+
? " It will be auto-promoted when ready."
|
|
234
|
+
: " It won't be auto-promoted when ready.";
|
|
235
|
+
success(`✓ Deployment #${deploymentId} submitted.${autoFrag}`);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Show deployment promoted message
|
|
240
|
+
*/
|
|
241
|
+
export function showDeploymentPromoted(): void {
|
|
242
|
+
success("✓ Deployment promoted");
|
|
243
|
+
}
|
|
244
|
+
|
|
221
245
|
/**
|
|
222
246
|
* Show validating deployment message
|
|
223
247
|
*/
|
|
@@ -424,6 +448,9 @@ export const output = {
|
|
|
424
448
|
showNoChanges,
|
|
425
449
|
showWaitingForDeployment,
|
|
426
450
|
showDeploymentReady,
|
|
451
|
+
showWaitingForPromote,
|
|
452
|
+
showDeploymentPromoted,
|
|
453
|
+
showDeploymentSubmitted,
|
|
427
454
|
showDeploymentLive,
|
|
428
455
|
showValidatingDeployment,
|
|
429
456
|
showDeploySuccess,
|
package/src/test/handlers.ts
CHANGED
|
@@ -86,25 +86,21 @@ export function createDeploySuccessResponse(options?: {
|
|
|
86
86
|
export function createDeploymentStatusResponse(options?: {
|
|
87
87
|
deploymentId?: string;
|
|
88
88
|
status?: string;
|
|
89
|
+
live?: boolean;
|
|
89
90
|
}) {
|
|
91
|
+
const status = options?.status ?? "data_ready";
|
|
90
92
|
return {
|
|
91
93
|
result: "success",
|
|
92
94
|
deployment: {
|
|
93
95
|
id: options?.deploymentId ?? "deploy-123",
|
|
94
|
-
status
|
|
96
|
+
status,
|
|
97
|
+
// When the deployment is `data_ready` the default assumes the server
|
|
98
|
+
// has already auto-promoted it, which is what most tests exercise.
|
|
99
|
+
live: options?.live ?? status === "data_ready",
|
|
95
100
|
},
|
|
96
101
|
};
|
|
97
102
|
}
|
|
98
103
|
|
|
99
|
-
/**
|
|
100
|
-
* Create set-live success response (for /v1/deployments/:id/set-live endpoint)
|
|
101
|
-
*/
|
|
102
|
-
export function createSetLiveSuccessResponse() {
|
|
103
|
-
return {
|
|
104
|
-
result: "success",
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
|
|
108
104
|
/**
|
|
109
105
|
* Create deployments list response (for /v1/deployments endpoint)
|
|
110
106
|
*/
|