@hoststack.dev/sdk 0.8.0 → 0.8.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.
package/dist/index.d.cts CHANGED
@@ -28,20 +28,38 @@ interface Service {
28
28
  createdAt: string;
29
29
  updatedAt: string;
30
30
  }
31
+ type ServiceType = 'web_service' | 'private_service' | 'worker' | 'cron_job' | 'static_site';
32
+ type ServicePlan = 'pico' | 'nano' | 'micro' | 'starter' | 'standard' | 'pro_standard' | 'pro_large';
31
33
  interface CreateServiceInput {
32
34
  name: string;
33
- type: string;
34
- projectId?: string;
35
+ type: ServiceType;
36
+ projectId: number;
35
37
  /**
36
38
  * v66 P5: bind the new service to a specific environment in the
37
39
  * project. Omit to default to the project's Production env. Find or
38
40
  * list envs with `client.environments.list(teamId, projectId)`.
39
41
  */
40
42
  environmentId?: number;
41
- gitUrl?: string;
43
+ /** Connect a previously-linked GitHub repo by id. Mutually exclusive with gitlabRepoId/bitbucketRepoId/dockerImage. */
44
+ githubRepoId?: number;
45
+ gitlabRepoId?: number;
46
+ bitbucketRepoId?: number;
42
47
  branch?: string;
48
+ rootDirectory?: string;
49
+ installCommand?: string;
43
50
  buildCommand?: string;
44
51
  startCommand?: string;
52
+ plan?: ServicePlan;
53
+ /** Cron expression — required when `type: 'cron_job'`. */
54
+ cronSchedule?: string;
55
+ /** Static-site build output path, e.g. `dist`. */
56
+ publishPath?: string;
57
+ /** Pre-built image to deploy instead of building from source. */
58
+ dockerImage?: string;
59
+ /** Runtime hint (`node`, `bun`, `python`, …). Auto-detected when omitted. */
60
+ runtime?: string;
61
+ autoDeploy?: boolean;
62
+ multistage?: boolean;
45
63
  }
46
64
  /**
47
65
  * Fields that live on the `services` row — write via PATCH /services/:tid/:sid.
@@ -171,7 +189,10 @@ interface Deploy {
171
189
  totalDurationMs?: number;
172
190
  }
173
191
  interface TriggerDeployInput {
174
- clearCache?: boolean;
192
+ /** Override the commit to build. Defaults to the tip of the service's tracked branch. */
193
+ commitHash?: string;
194
+ /** Override the branch to build. Defaults to the service's configured branch. */
195
+ branch?: string;
175
196
  }
176
197
  /** Managed database engines supported by HostStack. */
177
198
  type DatabaseEngine = 'postgres' | 'redis' | 'mysql' | 'mariadb' | 'mongodb';
@@ -216,11 +237,12 @@ interface UpdateDatabaseInput {
216
237
  diskSizeGb?: number;
217
238
  }
218
239
  interface DatabaseCredentials {
219
- host: string;
220
- port: number;
221
- username: string;
240
+ /** Null while the database is still provisioning. */
241
+ host: string | null;
242
+ port: number | null;
243
+ username: string | null;
222
244
  password: string;
223
- database: string;
245
+ databaseName: string;
224
246
  connectionUrl: string;
225
247
  }
226
248
  /**
@@ -245,7 +267,7 @@ interface CreateVolumeInput {
245
267
  name: string;
246
268
  /** In-container absolute path where the volume mounts. */
247
269
  mountPath: string;
248
- /** Disk size in GB. 1–100, default 1. Counts against your plan's
270
+ /** Disk size in GB. 1–1024, default 1. Counts against your plan's
249
271
  * storage quota and is metered for billing. */
250
272
  sizeGb?: number;
251
273
  }
@@ -264,16 +286,22 @@ interface Domain {
264
286
  }
265
287
  interface AddDomainInput {
266
288
  domain: string;
267
- serviceId?: string;
289
+ /** Numeric service id (required). Pass `IdInput` to the resource method instead if you have a publicId. */
290
+ serviceId: number;
291
+ /** Path-prefix routing — point one hostname at multiple services (e.g. `/api` → api svc, `/` → web svc). */
292
+ pathPrefix?: string | null;
268
293
  }
269
294
  interface UpdateDomainInput {
270
- serviceId?: string;
295
+ /** Promote this hostname to the service's primary domain (sets the canonical URL header). */
296
+ isPrimary?: boolean;
297
+ /** When set, the hostname serves a 301 redirect to this absolute URL instead of routing traffic. */
298
+ redirectTo?: string | null;
271
299
  }
272
300
  interface EnvVar {
273
301
  id: number;
274
- publicId: string;
275
302
  key: string;
276
303
  value: string;
304
+ target: EnvVarTarget;
277
305
  isSecret: boolean;
278
306
  }
279
307
  type EnvVarTarget = 'build' | 'runtime' | 'both';
@@ -284,7 +312,6 @@ interface CreateEnvVarInput {
284
312
  isSecret?: boolean;
285
313
  }
286
314
  interface UpdateEnvVarInput {
287
- key?: string;
288
315
  value?: string;
289
316
  target?: EnvVarTarget;
290
317
  isSecret?: boolean;
@@ -320,11 +347,34 @@ interface MeResponse {
320
347
  };
321
348
  stripeMode?: string;
322
349
  }
323
- interface ServiceMetrics {
324
- cpu: number;
325
- memory: number;
326
- network: number;
327
- requests: number;
350
+ /**
351
+ * A single point in a service metrics time series. Same shape used for
352
+ * the latest-snapshot and history endpoints.
353
+ */
354
+ interface ServiceMetricsPoint {
355
+ timestamp: string;
356
+ cpuPercent: number;
357
+ memoryUsedMb: number;
358
+ memoryLimitMb: number;
359
+ networkRxBytes: number;
360
+ networkTxBytes: number;
361
+ diskUsedMb: number;
362
+ }
363
+ /**
364
+ * Latest-snapshot response from `services.getMetrics`. `metrics` is null
365
+ * before the first agent sample lands; `serverOverview` is null when the
366
+ * service is not currently placed on a worker (suspended, between
367
+ * deploys, etc).
368
+ */
369
+ interface ServiceMetricsSnapshot {
370
+ metrics: ServiceMetricsPoint | null;
371
+ serverOverview: {
372
+ cpuPercent: number;
373
+ memoryUsedMb: number;
374
+ memoryLimitMb: number;
375
+ diskUsedMb: number;
376
+ containerCount: number;
377
+ } | null;
328
378
  }
329
379
  interface CronExecution {
330
380
  id: number;
@@ -369,8 +419,11 @@ declare class CronResource {
369
419
  declare class DatabasesResource {
370
420
  private client;
371
421
  constructor(client: HostStack);
372
- /** List all databases for a project. */
373
- list(teamId: IdInput, projectId: IdInput): Promise<{
422
+ /**
423
+ * List databases for the team. Pass `projectId` to scope to one
424
+ * project; omit it to list every database the team owns.
425
+ */
426
+ list(teamId: IdInput, projectId?: IdInput): Promise<{
374
427
  databases: Database[];
375
428
  }>;
376
429
  /** Get a single database by ID. */
@@ -797,10 +850,14 @@ declare class ServicesResource {
797
850
  suspend(teamId: IdInput, serviceId: IdInput): Promise<void>;
798
851
  /** Resume a suspended service. */
799
852
  resume(teamId: IdInput, serviceId: IdInput): Promise<void>;
800
- /** Get service metrics. */
801
- getMetrics(teamId: IdInput, serviceId: IdInput): Promise<{
802
- metrics: ServiceMetrics;
803
- }>;
853
+ /**
854
+ * Get the latest metrics snapshot for a service.
855
+ *
856
+ * Returns `metrics: null` before the first agent sample lands;
857
+ * `serverOverview: null` when the service is not currently placed
858
+ * (suspended, between deploys, etc).
859
+ */
860
+ getMetrics(teamId: IdInput, serviceId: IdInput): Promise<ServiceMetricsSnapshot>;
804
861
  /**
805
862
  * Get a metrics time series for a service.
806
863
  *
@@ -847,7 +904,7 @@ declare class ServicesResource {
847
904
  since?: string;
848
905
  until?: string;
849
906
  stream?: 'stdout' | 'stderr';
850
- level?: 'stdout' | 'stderr' | 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal';
907
+ level?: 'stdout' | 'stderr' | 'debug' | 'info' | 'warn' | 'error';
851
908
  search?: string;
852
909
  grep?: string;
853
910
  countOnly?: boolean;
@@ -948,10 +1005,6 @@ type ResolveScope = {
948
1005
  kind: 'volume';
949
1006
  teamId: number;
950
1007
  serviceId: number;
951
- } | {
952
- kind: 'envVar';
953
- teamId: number;
954
- serviceId: number;
955
1008
  } | {
956
1009
  kind: 'environment';
957
1010
  teamId: number;
@@ -1009,16 +1062,29 @@ declare class HostStack {
1009
1062
 
1010
1063
  declare class HostStackError extends Error {
1011
1064
  readonly statusCode: number;
1012
- constructor(statusCode: number, message: string);
1065
+ /** Raw response body, if it parsed as JSON. Useful for surfacing field-level validation errors. */
1066
+ readonly body: unknown;
1067
+ constructor(statusCode: number, message: string, body?: unknown);
1013
1068
  }
1014
1069
  declare class AuthenticationError extends HostStackError {
1015
- constructor(message?: string);
1070
+ constructor(message?: string, body?: unknown);
1071
+ }
1072
+ declare class ForbiddenError extends HostStackError {
1073
+ constructor(message?: string, body?: unknown);
1016
1074
  }
1017
1075
  declare class NotFoundError extends HostStackError {
1018
- constructor(message?: string);
1076
+ constructor(message?: string, body?: unknown);
1077
+ }
1078
+ declare class ConflictError extends HostStackError {
1079
+ constructor(message?: string, body?: unknown);
1019
1080
  }
1020
1081
  declare class RateLimitError extends HostStackError {
1021
- constructor(message?: string);
1082
+ /**
1083
+ * Seconds to wait before retrying, parsed from the `Retry-After` response
1084
+ * header. `undefined` if the server didn't send one.
1085
+ */
1086
+ readonly retryAfter: number | undefined;
1087
+ constructor(message?: string, retryAfter?: number, body?: unknown);
1022
1088
  }
1023
1089
 
1024
1090
  /**
@@ -1051,4 +1117,4 @@ declare function buildPaginationQuery(params?: PaginationParams): string;
1051
1117
  */
1052
1118
  declare function wrapArray<T>(items: T[], params?: PaginationParams): PaginatedResponse<T>;
1053
1119
 
1054
- export { type ActivityLogEntry, type AddDomainInput, AuthenticationError, type BulkSetEnvVarsInput, type CreateDatabaseInput, type CreateEnvVarInput, type CreateEnvironmentInput, type CreateProjectInput, type CreateServiceInput, type CronExecution, type Database, type DatabaseCredentials, type Deploy, type DeployListResponse, type DeployLogEntry, type Domain, type EnvVar, type Environment, HostStack, HostStackError, type HostStackOptions, type LogEntry$1 as LogEntry, type MeResponse, NotFoundError, type NotificationChannel, type NotificationChannelEvent, type NotificationChannelType, type PaginatedResponse, type PaginationParams, type Project, RateLimitError, type Service, type ServiceConfig, type ServiceMetrics, type StreamLogsOptions, type Team, type TriggerDeployInput, type UpdateDatabaseInput, type UpdateDomainInput, type UpdateEnvVarInput, type UpdateEnvironmentInput, type UpdateProjectInput, type UpdateServiceConfigInput, type UpdateServiceInput, type User, buildPaginationQuery, wrapArray };
1120
+ export { type ActivityLogEntry, type AddDomainInput, AuthenticationError, type BulkSetEnvVarsInput, ConflictError, type CreateDatabaseInput, type CreateEnvVarInput, type CreateEnvironmentInput, type CreateProjectInput, type CreateServiceInput, type CreateVolumeInput, type CronExecution, type Database, type DatabaseCredentials, type Deploy, type DeployListResponse, type DeployLogEntry, type Domain, type EnvVar, type Environment, ForbiddenError, HostStack, HostStackError, type HostStackOptions, type IdInput, type LogEntry$1 as LogEntry, type MeResponse, NotFoundError, type NotificationChannel, type NotificationChannelEvent, type NotificationChannelType, type PaginatedResponse, type PaginationParams, type Project, RateLimitError, type Service, type ServiceConfig, type ServiceMetricsPoint, type ServiceMetricsSnapshot, type ServicePlan, type ServiceType, type StreamLogsOptions, type Team, type TriggerDeployInput, type UpdateDatabaseInput, type UpdateDomainInput, type UpdateEnvVarInput, type UpdateEnvironmentInput, type UpdateProjectInput, type UpdateServiceConfigInput, type UpdateServiceInput, type UpdateVolumeInput, type User, type Volume, buildPaginationQuery, wrapArray };
package/dist/index.d.ts CHANGED
@@ -28,20 +28,38 @@ interface Service {
28
28
  createdAt: string;
29
29
  updatedAt: string;
30
30
  }
31
+ type ServiceType = 'web_service' | 'private_service' | 'worker' | 'cron_job' | 'static_site';
32
+ type ServicePlan = 'pico' | 'nano' | 'micro' | 'starter' | 'standard' | 'pro_standard' | 'pro_large';
31
33
  interface CreateServiceInput {
32
34
  name: string;
33
- type: string;
34
- projectId?: string;
35
+ type: ServiceType;
36
+ projectId: number;
35
37
  /**
36
38
  * v66 P5: bind the new service to a specific environment in the
37
39
  * project. Omit to default to the project's Production env. Find or
38
40
  * list envs with `client.environments.list(teamId, projectId)`.
39
41
  */
40
42
  environmentId?: number;
41
- gitUrl?: string;
43
+ /** Connect a previously-linked GitHub repo by id. Mutually exclusive with gitlabRepoId/bitbucketRepoId/dockerImage. */
44
+ githubRepoId?: number;
45
+ gitlabRepoId?: number;
46
+ bitbucketRepoId?: number;
42
47
  branch?: string;
48
+ rootDirectory?: string;
49
+ installCommand?: string;
43
50
  buildCommand?: string;
44
51
  startCommand?: string;
52
+ plan?: ServicePlan;
53
+ /** Cron expression — required when `type: 'cron_job'`. */
54
+ cronSchedule?: string;
55
+ /** Static-site build output path, e.g. `dist`. */
56
+ publishPath?: string;
57
+ /** Pre-built image to deploy instead of building from source. */
58
+ dockerImage?: string;
59
+ /** Runtime hint (`node`, `bun`, `python`, …). Auto-detected when omitted. */
60
+ runtime?: string;
61
+ autoDeploy?: boolean;
62
+ multistage?: boolean;
45
63
  }
46
64
  /**
47
65
  * Fields that live on the `services` row — write via PATCH /services/:tid/:sid.
@@ -171,7 +189,10 @@ interface Deploy {
171
189
  totalDurationMs?: number;
172
190
  }
173
191
  interface TriggerDeployInput {
174
- clearCache?: boolean;
192
+ /** Override the commit to build. Defaults to the tip of the service's tracked branch. */
193
+ commitHash?: string;
194
+ /** Override the branch to build. Defaults to the service's configured branch. */
195
+ branch?: string;
175
196
  }
176
197
  /** Managed database engines supported by HostStack. */
177
198
  type DatabaseEngine = 'postgres' | 'redis' | 'mysql' | 'mariadb' | 'mongodb';
@@ -216,11 +237,12 @@ interface UpdateDatabaseInput {
216
237
  diskSizeGb?: number;
217
238
  }
218
239
  interface DatabaseCredentials {
219
- host: string;
220
- port: number;
221
- username: string;
240
+ /** Null while the database is still provisioning. */
241
+ host: string | null;
242
+ port: number | null;
243
+ username: string | null;
222
244
  password: string;
223
- database: string;
245
+ databaseName: string;
224
246
  connectionUrl: string;
225
247
  }
226
248
  /**
@@ -245,7 +267,7 @@ interface CreateVolumeInput {
245
267
  name: string;
246
268
  /** In-container absolute path where the volume mounts. */
247
269
  mountPath: string;
248
- /** Disk size in GB. 1–100, default 1. Counts against your plan's
270
+ /** Disk size in GB. 1–1024, default 1. Counts against your plan's
249
271
  * storage quota and is metered for billing. */
250
272
  sizeGb?: number;
251
273
  }
@@ -264,16 +286,22 @@ interface Domain {
264
286
  }
265
287
  interface AddDomainInput {
266
288
  domain: string;
267
- serviceId?: string;
289
+ /** Numeric service id (required). Pass `IdInput` to the resource method instead if you have a publicId. */
290
+ serviceId: number;
291
+ /** Path-prefix routing — point one hostname at multiple services (e.g. `/api` → api svc, `/` → web svc). */
292
+ pathPrefix?: string | null;
268
293
  }
269
294
  interface UpdateDomainInput {
270
- serviceId?: string;
295
+ /** Promote this hostname to the service's primary domain (sets the canonical URL header). */
296
+ isPrimary?: boolean;
297
+ /** When set, the hostname serves a 301 redirect to this absolute URL instead of routing traffic. */
298
+ redirectTo?: string | null;
271
299
  }
272
300
  interface EnvVar {
273
301
  id: number;
274
- publicId: string;
275
302
  key: string;
276
303
  value: string;
304
+ target: EnvVarTarget;
277
305
  isSecret: boolean;
278
306
  }
279
307
  type EnvVarTarget = 'build' | 'runtime' | 'both';
@@ -284,7 +312,6 @@ interface CreateEnvVarInput {
284
312
  isSecret?: boolean;
285
313
  }
286
314
  interface UpdateEnvVarInput {
287
- key?: string;
288
315
  value?: string;
289
316
  target?: EnvVarTarget;
290
317
  isSecret?: boolean;
@@ -320,11 +347,34 @@ interface MeResponse {
320
347
  };
321
348
  stripeMode?: string;
322
349
  }
323
- interface ServiceMetrics {
324
- cpu: number;
325
- memory: number;
326
- network: number;
327
- requests: number;
350
+ /**
351
+ * A single point in a service metrics time series. Same shape used for
352
+ * the latest-snapshot and history endpoints.
353
+ */
354
+ interface ServiceMetricsPoint {
355
+ timestamp: string;
356
+ cpuPercent: number;
357
+ memoryUsedMb: number;
358
+ memoryLimitMb: number;
359
+ networkRxBytes: number;
360
+ networkTxBytes: number;
361
+ diskUsedMb: number;
362
+ }
363
+ /**
364
+ * Latest-snapshot response from `services.getMetrics`. `metrics` is null
365
+ * before the first agent sample lands; `serverOverview` is null when the
366
+ * service is not currently placed on a worker (suspended, between
367
+ * deploys, etc).
368
+ */
369
+ interface ServiceMetricsSnapshot {
370
+ metrics: ServiceMetricsPoint | null;
371
+ serverOverview: {
372
+ cpuPercent: number;
373
+ memoryUsedMb: number;
374
+ memoryLimitMb: number;
375
+ diskUsedMb: number;
376
+ containerCount: number;
377
+ } | null;
328
378
  }
329
379
  interface CronExecution {
330
380
  id: number;
@@ -369,8 +419,11 @@ declare class CronResource {
369
419
  declare class DatabasesResource {
370
420
  private client;
371
421
  constructor(client: HostStack);
372
- /** List all databases for a project. */
373
- list(teamId: IdInput, projectId: IdInput): Promise<{
422
+ /**
423
+ * List databases for the team. Pass `projectId` to scope to one
424
+ * project; omit it to list every database the team owns.
425
+ */
426
+ list(teamId: IdInput, projectId?: IdInput): Promise<{
374
427
  databases: Database[];
375
428
  }>;
376
429
  /** Get a single database by ID. */
@@ -797,10 +850,14 @@ declare class ServicesResource {
797
850
  suspend(teamId: IdInput, serviceId: IdInput): Promise<void>;
798
851
  /** Resume a suspended service. */
799
852
  resume(teamId: IdInput, serviceId: IdInput): Promise<void>;
800
- /** Get service metrics. */
801
- getMetrics(teamId: IdInput, serviceId: IdInput): Promise<{
802
- metrics: ServiceMetrics;
803
- }>;
853
+ /**
854
+ * Get the latest metrics snapshot for a service.
855
+ *
856
+ * Returns `metrics: null` before the first agent sample lands;
857
+ * `serverOverview: null` when the service is not currently placed
858
+ * (suspended, between deploys, etc).
859
+ */
860
+ getMetrics(teamId: IdInput, serviceId: IdInput): Promise<ServiceMetricsSnapshot>;
804
861
  /**
805
862
  * Get a metrics time series for a service.
806
863
  *
@@ -847,7 +904,7 @@ declare class ServicesResource {
847
904
  since?: string;
848
905
  until?: string;
849
906
  stream?: 'stdout' | 'stderr';
850
- level?: 'stdout' | 'stderr' | 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal';
907
+ level?: 'stdout' | 'stderr' | 'debug' | 'info' | 'warn' | 'error';
851
908
  search?: string;
852
909
  grep?: string;
853
910
  countOnly?: boolean;
@@ -948,10 +1005,6 @@ type ResolveScope = {
948
1005
  kind: 'volume';
949
1006
  teamId: number;
950
1007
  serviceId: number;
951
- } | {
952
- kind: 'envVar';
953
- teamId: number;
954
- serviceId: number;
955
1008
  } | {
956
1009
  kind: 'environment';
957
1010
  teamId: number;
@@ -1009,16 +1062,29 @@ declare class HostStack {
1009
1062
 
1010
1063
  declare class HostStackError extends Error {
1011
1064
  readonly statusCode: number;
1012
- constructor(statusCode: number, message: string);
1065
+ /** Raw response body, if it parsed as JSON. Useful for surfacing field-level validation errors. */
1066
+ readonly body: unknown;
1067
+ constructor(statusCode: number, message: string, body?: unknown);
1013
1068
  }
1014
1069
  declare class AuthenticationError extends HostStackError {
1015
- constructor(message?: string);
1070
+ constructor(message?: string, body?: unknown);
1071
+ }
1072
+ declare class ForbiddenError extends HostStackError {
1073
+ constructor(message?: string, body?: unknown);
1016
1074
  }
1017
1075
  declare class NotFoundError extends HostStackError {
1018
- constructor(message?: string);
1076
+ constructor(message?: string, body?: unknown);
1077
+ }
1078
+ declare class ConflictError extends HostStackError {
1079
+ constructor(message?: string, body?: unknown);
1019
1080
  }
1020
1081
  declare class RateLimitError extends HostStackError {
1021
- constructor(message?: string);
1082
+ /**
1083
+ * Seconds to wait before retrying, parsed from the `Retry-After` response
1084
+ * header. `undefined` if the server didn't send one.
1085
+ */
1086
+ readonly retryAfter: number | undefined;
1087
+ constructor(message?: string, retryAfter?: number, body?: unknown);
1022
1088
  }
1023
1089
 
1024
1090
  /**
@@ -1051,4 +1117,4 @@ declare function buildPaginationQuery(params?: PaginationParams): string;
1051
1117
  */
1052
1118
  declare function wrapArray<T>(items: T[], params?: PaginationParams): PaginatedResponse<T>;
1053
1119
 
1054
- export { type ActivityLogEntry, type AddDomainInput, AuthenticationError, type BulkSetEnvVarsInput, type CreateDatabaseInput, type CreateEnvVarInput, type CreateEnvironmentInput, type CreateProjectInput, type CreateServiceInput, type CronExecution, type Database, type DatabaseCredentials, type Deploy, type DeployListResponse, type DeployLogEntry, type Domain, type EnvVar, type Environment, HostStack, HostStackError, type HostStackOptions, type LogEntry$1 as LogEntry, type MeResponse, NotFoundError, type NotificationChannel, type NotificationChannelEvent, type NotificationChannelType, type PaginatedResponse, type PaginationParams, type Project, RateLimitError, type Service, type ServiceConfig, type ServiceMetrics, type StreamLogsOptions, type Team, type TriggerDeployInput, type UpdateDatabaseInput, type UpdateDomainInput, type UpdateEnvVarInput, type UpdateEnvironmentInput, type UpdateProjectInput, type UpdateServiceConfigInput, type UpdateServiceInput, type User, buildPaginationQuery, wrapArray };
1120
+ export { type ActivityLogEntry, type AddDomainInput, AuthenticationError, type BulkSetEnvVarsInput, ConflictError, type CreateDatabaseInput, type CreateEnvVarInput, type CreateEnvironmentInput, type CreateProjectInput, type CreateServiceInput, type CreateVolumeInput, type CronExecution, type Database, type DatabaseCredentials, type Deploy, type DeployListResponse, type DeployLogEntry, type Domain, type EnvVar, type Environment, ForbiddenError, HostStack, HostStackError, type HostStackOptions, type IdInput, type LogEntry$1 as LogEntry, type MeResponse, NotFoundError, type NotificationChannel, type NotificationChannelEvent, type NotificationChannelType, type PaginatedResponse, type PaginationParams, type Project, RateLimitError, type Service, type ServiceConfig, type ServiceMetricsPoint, type ServiceMetricsSnapshot, type ServicePlan, type ServiceType, type StreamLogsOptions, type Team, type TriggerDeployInput, type UpdateDatabaseInput, type UpdateDomainInput, type UpdateEnvVarInput, type UpdateEnvironmentInput, type UpdateProjectInput, type UpdateServiceConfigInput, type UpdateServiceInput, type UpdateVolumeInput, type User, type Volume, buildPaginationQuery, wrapArray };
package/dist/index.js CHANGED
@@ -1,28 +1,49 @@
1
1
  // src/errors.ts
2
2
  var HostStackError = class extends Error {
3
3
  statusCode;
4
- constructor(statusCode, message) {
4
+ /** Raw response body, if it parsed as JSON. Useful for surfacing field-level validation errors. */
5
+ body;
6
+ constructor(statusCode, message, body) {
5
7
  super(message);
6
8
  this.name = "HostStackError";
7
9
  this.statusCode = statusCode;
10
+ this.body = body;
8
11
  }
9
12
  };
10
13
  var AuthenticationError = class extends HostStackError {
11
- constructor(message = "Authentication failed. Check your API key.") {
12
- super(401, message);
14
+ constructor(message = "Authentication failed \u2014 check your API key.", body) {
15
+ super(401, message, body);
13
16
  this.name = "AuthenticationError";
14
17
  }
15
18
  };
19
+ var ForbiddenError = class extends HostStackError {
20
+ constructor(message = "Permission denied \u2014 API key lacks the required scope.", body) {
21
+ super(403, message, body);
22
+ this.name = "ForbiddenError";
23
+ }
24
+ };
16
25
  var NotFoundError = class extends HostStackError {
17
- constructor(message = "Resource not found.") {
18
- super(404, message);
26
+ constructor(message = "Resource not found.", body) {
27
+ super(404, message, body);
19
28
  this.name = "NotFoundError";
20
29
  }
21
30
  };
31
+ var ConflictError = class extends HostStackError {
32
+ constructor(message = "Conflict \u2014 the resource state prevents this operation.", body) {
33
+ super(409, message, body);
34
+ this.name = "ConflictError";
35
+ }
36
+ };
22
37
  var RateLimitError = class extends HostStackError {
23
- constructor(message = "Rate limit exceeded. Try again later.") {
24
- super(429, message);
38
+ /**
39
+ * Seconds to wait before retrying, parsed from the `Retry-After` response
40
+ * header. `undefined` if the server didn't send one.
41
+ */
42
+ retryAfter;
43
+ constructor(message = "Rate limit exceeded \u2014 back off and retry.", retryAfter, body) {
44
+ super(429, message, body);
25
45
  this.name = "RateLimitError";
46
+ this.retryAfter = retryAfter;
26
47
  }
27
48
  };
28
49
 
@@ -67,9 +88,15 @@ var DatabasesResource = class {
67
88
  constructor(client) {
68
89
  this.client = client;
69
90
  }
70
- /** List all databases for a project. */
91
+ /**
92
+ * List databases for the team. Pass `projectId` to scope to one
93
+ * project; omit it to list every database the team owns.
94
+ */
71
95
  async list(teamId, projectId) {
72
96
  const tid = await this.client.resolveId(teamId, { kind: "team" });
97
+ if (projectId === void 0) {
98
+ return this.client.request("GET", `/api/databases/${tid}`);
99
+ }
73
100
  const pid = await this.client.resolveId(projectId, { kind: "project", teamId: tid });
74
101
  return this.client.request("GET", `/api/databases/${tid}?projectId=${pid}`);
75
102
  }
@@ -372,22 +399,24 @@ var EnvVarsResource = class {
372
399
  async update(teamId, serviceId, envVarId, data) {
373
400
  const tid = await this.client.resolveId(teamId, { kind: "team" });
374
401
  const sid = await this.client.resolveId(serviceId, { kind: "service", teamId: tid });
375
- const eid = await this.client.resolveId(envVarId, {
376
- kind: "envVar",
377
- teamId: tid,
378
- serviceId: sid
379
- });
402
+ const eid = typeof envVarId === "number" ? envVarId : Number.parseInt(envVarId, 10);
403
+ if (Number.isNaN(eid)) {
404
+ throw new Error(
405
+ `Invalid envVarId "${envVarId}": expected a numeric id (env vars have no publicId \u2014 read it from list()).`
406
+ );
407
+ }
380
408
  return this.client.request("PATCH", `/api/services/${tid}/${sid}/env/${eid}`, data);
381
409
  }
382
410
  /** Delete an environment variable. */
383
411
  async delete(teamId, serviceId, envVarId) {
384
412
  const tid = await this.client.resolveId(teamId, { kind: "team" });
385
413
  const sid = await this.client.resolveId(serviceId, { kind: "service", teamId: tid });
386
- const eid = await this.client.resolveId(envVarId, {
387
- kind: "envVar",
388
- teamId: tid,
389
- serviceId: sid
390
- });
414
+ const eid = typeof envVarId === "number" ? envVarId : Number.parseInt(envVarId, 10);
415
+ if (Number.isNaN(eid)) {
416
+ throw new Error(
417
+ `Invalid envVarId "${envVarId}": expected a numeric id (env vars have no publicId \u2014 read it from list()).`
418
+ );
419
+ }
391
420
  return this.client.request("DELETE", `/api/services/${tid}/${sid}/env/${eid}`);
392
421
  }
393
422
  /** Bulk set environment variables (create or update). */
@@ -604,7 +633,13 @@ var ServicesResource = class {
604
633
  const sid = await this.client.resolveId(serviceId, { kind: "service", teamId: tid });
605
634
  return this.client.request("POST", `/api/services/${tid}/${sid}/resume`);
606
635
  }
607
- /** Get service metrics. */
636
+ /**
637
+ * Get the latest metrics snapshot for a service.
638
+ *
639
+ * Returns `metrics: null` before the first agent sample lands;
640
+ * `serverOverview: null` when the service is not currently placed
641
+ * (suspended, between deploys, etc).
642
+ */
608
643
  async getMetrics(teamId, serviceId) {
609
644
  const tid = await this.client.resolveId(teamId, { kind: "team" });
610
645
  const sid = await this.client.resolveId(serviceId, { kind: "service", teamId: tid });
@@ -748,8 +783,7 @@ var PREFIX = {
748
783
  database: "db_",
749
784
  domain: "dom_",
750
785
  volume: "vol_",
751
- envVar: "env_",
752
- environment: "environment_",
786
+ environment: "env_",
753
787
  cronExecution: "cjob_"
754
788
  };
755
789
  var HostStack = class {
@@ -820,13 +854,20 @@ var HostStack = class {
820
854
  const message = data.error ?? `HTTP ${res.status}`;
821
855
  switch (res.status) {
822
856
  case 401:
823
- throw new AuthenticationError(message);
857
+ throw new AuthenticationError(message, data);
858
+ case 403:
859
+ throw new ForbiddenError(message, data);
824
860
  case 404:
825
- throw new NotFoundError(message);
826
- case 429:
827
- throw new RateLimitError(message);
861
+ throw new NotFoundError(message, data);
862
+ case 409:
863
+ throw new ConflictError(message, data);
864
+ case 429: {
865
+ const header = res.headers.get("Retry-After");
866
+ const retryAfter = header && /^\d+$/.test(header) ? Number(header) : void 0;
867
+ throw new RateLimitError(message, retryAfter, data);
868
+ }
828
869
  default:
829
- throw new HostStackError(res.status, message);
870
+ throw new HostStackError(res.status, message, data);
830
871
  }
831
872
  }
832
873
  if (res.status === 204) {
@@ -902,13 +943,6 @@ var HostStack = class {
902
943
  );
903
944
  return r.domains ?? [];
904
945
  }
905
- case "envVar": {
906
- const r = await this.request(
907
- "GET",
908
- `/api/services/${scope.teamId}/${scope.serviceId}/env`
909
- );
910
- return r.envVars ?? [];
911
- }
912
946
  case "volume": {
913
947
  const r = await this.request("GET", `/api/services/${scope.teamId}/${scope.serviceId}/volumes`);
914
948
  return r.volumes ?? [];
@@ -941,7 +975,6 @@ function cacheScope(scope) {
941
975
  return `${scope.kind}:${scope.teamId}`;
942
976
  case "deploy":
943
977
  case "volume":
944
- case "envVar":
945
978
  case "cronExecution":
946
979
  return `${scope.kind}:${scope.teamId}:${scope.serviceId}`;
947
980
  }
@@ -968,6 +1001,6 @@ function wrapArray(items, params) {
968
1001
  };
969
1002
  }
970
1003
 
971
- export { AuthenticationError, HostStack, HostStackError, NotFoundError, RateLimitError, buildPaginationQuery, wrapArray };
1004
+ export { AuthenticationError, ConflictError, ForbiddenError, HostStack, HostStackError, NotFoundError, RateLimitError, buildPaginationQuery, wrapArray };
972
1005
  //# sourceMappingURL=index.js.map
973
1006
  //# sourceMappingURL=index.js.map