Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 10 additions & 9 deletions src/commands/deployments/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { getProjectConfig } from '../../lib/config.js';
import { requireAuth } from '../../lib/credentials.js';
import { handleError, getRootOpts, CLIError, ProjectNotLinkedError } from '../../lib/errors.js';
import { outputJson } from '../../lib/output.js';
import type { CreateDeploymentResponse, StartDeploymentRequest, SiteDeployment } from '../../types.js';
import type { CreateDeploymentResponse, StartDeploymentRequest, DeploymentSchema } from '../../types.js';
import { reportCliUsage } from '../../lib/skills.js';

const POLL_INTERVAL_MS = 5_000;
Expand Down Expand Up @@ -68,7 +68,7 @@ export interface DeployProjectOptions {

export interface DeployProjectResult {
deploymentId: string;
deployment: SiteDeployment | null;
deployment: DeploymentSchema | null;
isReady: boolean;
liveUrl: string | null;
}
Expand Down Expand Up @@ -119,20 +119,21 @@ export async function deployProject(opts: DeployProjectOptions): Promise<DeployP
// Step 5: Poll for deployment status
s?.message('Building and deploying...');
const startTime = Date.now();
let deployment: SiteDeployment | null = null;
let deployment: DeploymentSchema | null = null;

while (Date.now() - startTime < POLL_TIMEOUT_MS) {
await new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));
try {
const statusRes = await ossFetch(`/api/deployments/${deploymentId}`);
deployment = (await statusRes.json()) as SiteDeployment;
deployment = (await statusRes.json()) as DeploymentSchema;

if (deployment.status === 'ready' || deployment.status === 'READY') {
if (deployment.status === 'READY') {
break;
}
if (deployment.status === 'error' || deployment.status === 'ERROR' || deployment.status === 'canceled') {
if (deployment.status === 'ERROR' || deployment.status === 'CANCELED') {
s?.stop('Deployment failed');
throw new CLIError(deployment.error ?? `Deployment failed with status: ${deployment.status}`);
const errorMsg = (deployment.metadata as Record<string, unknown> | null)?.error as { errorMessage?: string } | undefined;
throw new CLIError(errorMsg?.errorMessage ?? `Deployment failed with status: ${deployment.status}`);
}

const elapsed = Math.round((Date.now() - startTime) / 1000);
Expand All @@ -143,8 +144,8 @@ export async function deployProject(opts: DeployProjectOptions): Promise<DeployP
}
}

const isReady = deployment?.status === 'ready' || deployment?.status === 'READY';
const liveUrl = isReady ? (deployment?.deploymentUrl ?? deployment?.url ?? null) : null;
const isReady = deployment?.status === 'READY';
const liveUrl = isReady ? (deployment?.url ?? null) : null;

return { deploymentId, deployment, isReady, liveUrl };
}
Expand Down
8 changes: 4 additions & 4 deletions src/commands/deployments/status.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { requireAuth } from '../../lib/credentials.js';
import { getProjectConfig } from '../../lib/config.js';
import { handleError, getRootOpts, ProjectNotLinkedError } from '../../lib/errors.js';
import { outputJson, outputTable } from '../../lib/output.js';
import type { SiteDeployment } from '../../types.js';
import type { DeploymentSchema } from '../../types.js';

export function registerDeploymentsStatusCommand(deploymentsCmd: Command): void {
deploymentsCmd
Expand All @@ -23,7 +23,7 @@ export function registerDeploymentsStatusCommand(deploymentsCmd: Command): void
}

const res = await ossFetch(`/api/deployments/${id}`);
const d = (await res.json()) as SiteDeployment;
const d = (await res.json()) as DeploymentSchema;

if (json) {
outputJson(d);
Expand All @@ -35,10 +35,10 @@ export function registerDeploymentsStatusCommand(deploymentsCmd: Command): void
['Status', d.status],
['Provider', d.provider ?? '-'],
['Provider ID', d.providerDeploymentId ?? '-'],
['URL', d.deploymentUrl ?? d.url ?? '-'],
['URL', d.url ?? '-'],
['Created', new Date(d.createdAt).toLocaleString()],
['Updated', new Date(d.updatedAt).toLocaleString()],
...(d.error ? [['Error', d.error]] : []),
...((d.metadata as Record<string, unknown> | null)?.error ? [['Error', ((d.metadata as Record<string, unknown>).error as { errorMessage?: string })?.errorMessage ?? 'Unknown error']] : []),
],
);
}
Expand Down
35 changes: 2 additions & 33 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,8 @@ export interface ApiError {
export type { ListFunctionsResponse, StorageBucketSchema, ListDeploymentsResponse,
DatabaseFunctionsResponse, DatabaseIndexesResponse, DatabasePoliciesResponse, DatabaseTriggersResponse,
CreateScheduleResponse, ListSchedulesResponse, GetScheduleResponse, ListExecutionLogsResponse,
ListSecretsResponse, GetSecretValueResponse, CreateSecretResponse, DeleteSecretResponse, UpdateSecretResponse
ListSecretsResponse, GetSecretValueResponse, CreateSecretResponse, DeleteSecretResponse, UpdateSecretResponse,
CreateDeploymentResponse, StartDeploymentRequest, DeploymentSchema
} from '@insforge/shared-schemas';

// Function deploy/update response types
Expand Down Expand Up @@ -138,41 +139,9 @@ export interface FunctionResponse {

// Deployment types (OSS - Vercel deployment)

export interface CreateDeploymentResponse {
id: string;
uploadUrl: string;
uploadFields: Record<string, string>;
}

export interface SiteDeployment {
id: string;
status: string;
provider: string;
providerDeploymentId: string | null;
// API returns "url"; some endpoints may use "deploymentUrl"
url: string | null;
deploymentUrl?: string | null;
error: string | null;
metadata: Record<string, unknown> | null;
createdAt: string;
updatedAt: string;
}

export interface DeploymentMetadata {
currentDeploymentId: string | null;
domain: string | null;
slug: string | null;
deploymentUrl: string | null;
}

export interface StartDeploymentRequest {
projectSettings?: {
buildCommand?: string | null;
outputDirectory?: string | null;
installCommand?: string | null;
devCommand?: string | null;
rootDirectory?: string | null;
};
envVars?: { key: string; value: string }[];
meta?: Record<string, string>;
}