@hoststack.dev/sdk 0.3.0 → 0.5.0

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
@@ -32,6 +32,12 @@ interface CreateServiceInput {
32
32
  name: string;
33
33
  type: string;
34
34
  projectId?: string;
35
+ /**
36
+ * v66 P5: bind the new service to a specific environment in the
37
+ * project. Omit to default to the project's Production env. Find or
38
+ * list envs with `client.environments.list(teamId, projectId)`.
39
+ */
40
+ environmentId?: number;
35
41
  gitUrl?: string;
36
42
  branch?: string;
37
43
  buildCommand?: string;
@@ -75,6 +81,15 @@ interface ServiceConfig {
75
81
  dockerImage?: string | null;
76
82
  registryUsername?: string | null;
77
83
  registryPassword?: string | null;
84
+ /**
85
+ * v72.2: applied to runtime logs at query time. Reflects what the
86
+ * service is currently configured to filter; null/absent means no
87
+ * filtering. See UpdateServiceConfigInput for the write side.
88
+ */
89
+ logFilterRules?: Array<{
90
+ pattern: string;
91
+ action: 'drop' | 'downgrade';
92
+ }> | null;
78
93
  }
79
94
  /**
80
95
  * Fields that live on the `service_config` row — write via PATCH
@@ -101,6 +116,18 @@ interface UpdateServiceConfigInput {
101
116
  dockerImage?: string | null;
102
117
  registryUsername?: string | null;
103
118
  registryPassword?: string | null;
119
+ /**
120
+ * v72.2: per-service runtime-log filter rules applied at query
121
+ * time. Each rule matches the message by case-insensitive
122
+ * substring; matching rows are either dropped or have their
123
+ * stream flipped from stderr → stdout. Pass an empty array to
124
+ * clear all rules; null/omitted leaves the existing rules in
125
+ * place. Capped at 50 rules.
126
+ */
127
+ logFilterRules?: Array<{
128
+ pattern: string;
129
+ action: 'drop' | 'downgrade';
130
+ }> | null;
104
131
  }
105
132
  interface Deploy {
106
133
  id: number;
@@ -112,6 +139,19 @@ interface Deploy {
112
139
  createdAt: string;
113
140
  startedAt?: string | null;
114
141
  finishedAt?: string | null;
142
+ /**
143
+ * Wall-clock for the docker build / image-pull step only.
144
+ * Null when the deploy didn't reach the build phase (cancelled
145
+ * pre-pickup) or used a pre-built image with no measured pull.
146
+ */
147
+ buildDurationMs?: number | null;
148
+ /**
149
+ * Wall-clock for the full deploy pipeline (build + container
150
+ * start + health-check + traffic switch + cleanup), computed at
151
+ * serialize time from finishedAt − startedAt. Absent for deploys
152
+ * still in-flight or that never reached `startedAt`.
153
+ */
154
+ totalDurationMs?: number;
115
155
  }
116
156
  interface TriggerDeployInput {
117
157
  clearCache?: boolean;
@@ -130,6 +170,8 @@ interface Database {
130
170
  plan?: string | null;
131
171
  region?: string | null;
132
172
  projectId: number;
173
+ diskSizeGb?: number;
174
+ memoryMb?: number;
133
175
  createdAt: string;
134
176
  updatedAt: string;
135
177
  }
@@ -137,12 +179,20 @@ interface CreateDatabaseInput {
137
179
  name: string;
138
180
  engine: DatabaseEngine;
139
181
  projectId: number;
182
+ /**
183
+ * v66 P5: bind the new database to a specific environment in the
184
+ * project. Omit to default to the project's Production env.
185
+ */
186
+ environmentId?: number;
140
187
  version?: string;
141
188
  plan?: 'free' | 'starter' | 'standard' | 'pro';
142
189
  region?: string;
143
190
  }
144
191
  interface UpdateDatabaseInput {
145
192
  name?: string;
193
+ plan?: 'free' | 'starter' | 'standard' | 'pro';
194
+ /** Grow the database disk in GB. Cannot shrink. */
195
+ diskSizeGb?: number;
146
196
  }
147
197
  interface DatabaseCredentials {
148
198
  host: string;
@@ -205,20 +255,24 @@ interface EnvVar {
205
255
  value: string;
206
256
  isSecret: boolean;
207
257
  }
258
+ type EnvVarTarget = 'build' | 'runtime' | 'both';
208
259
  interface CreateEnvVarInput {
209
260
  key: string;
210
261
  value: string;
262
+ target?: EnvVarTarget;
211
263
  isSecret?: boolean;
212
264
  }
213
265
  interface UpdateEnvVarInput {
214
266
  key?: string;
215
267
  value?: string;
268
+ target?: EnvVarTarget;
216
269
  isSecret?: boolean;
217
270
  }
218
271
  interface BulkSetEnvVarsInput {
219
- envVars: Array<{
272
+ vars: Array<{
220
273
  key: string;
221
274
  value: string;
275
+ target?: EnvVarTarget;
222
276
  isSecret?: boolean;
223
277
  }>;
224
278
  }
@@ -354,6 +408,15 @@ declare class DeploysResource {
354
408
  cancel(teamId: IdInput, serviceId: IdInput, deployId: IdInput): Promise<void>;
355
409
  /** Rollback to a previous deploy. */
356
410
  rollback(teamId: IdInput, serviceId: IdInput, deployId: IdInput): Promise<void>;
411
+ /**
412
+ * v66 P5: promote a built deploy to a sibling service in another
413
+ * environment. Reuses the source deploy's docker image (no rebuild).
414
+ * If no sibling service exists in the target env yet, the API auto-
415
+ * creates one by cloning the source service's config.
416
+ */
417
+ promote(teamId: IdInput, serviceId: IdInput, deployId: IdInput, targetEnvironmentId: number): Promise<{
418
+ deploy: Deploy;
419
+ }>;
357
420
  /**
358
421
  * Get build logs for a deploy.
359
422
  *
@@ -401,6 +464,76 @@ declare class DomainsResource {
401
464
  verify(teamId: IdInput, domainId: IdInput): Promise<void>;
402
465
  }
403
466
 
467
+ interface Environment {
468
+ id: number;
469
+ publicId: string;
470
+ projectId: number;
471
+ name: string;
472
+ type: 'production' | 'staging' | 'development' | 'preview';
473
+ isDefault: boolean;
474
+ isProtected: boolean;
475
+ createdAt: string;
476
+ updatedAt: string;
477
+ }
478
+ interface CreateEnvironmentInput {
479
+ name: string;
480
+ type: 'production' | 'staging' | 'development' | 'preview';
481
+ isProtected?: boolean;
482
+ }
483
+ interface UpdateEnvironmentInput {
484
+ name?: string;
485
+ isDefault?: boolean;
486
+ isProtected?: boolean;
487
+ }
488
+ /**
489
+ * v66 P5: programmatic env management. Each project has at least a
490
+ * Production env auto-created at project creation; you can add more
491
+ * via `create` and bind services/databases to them via the
492
+ * `environmentId` field on those resources' create inputs.
493
+ *
494
+ * @example
495
+ * ```ts
496
+ * const { environment: staging } = await client.environments.create(
497
+ * teamId,
498
+ * projectId,
499
+ * { name: 'Staging', type: 'staging' }
500
+ * );
501
+ * await client.services.create(teamId, {
502
+ * projectId,
503
+ * environmentId: staging.id,
504
+ * name: 'api',
505
+ * type: 'web_service',
506
+ * // ...
507
+ * });
508
+ * ```
509
+ */
510
+ declare class EnvironmentsResource {
511
+ private client;
512
+ constructor(client: HostStack);
513
+ /** List all environments for a project. */
514
+ list(teamId: IdInput, projectId: IdInput): Promise<{
515
+ environments: Environment[];
516
+ }>;
517
+ /** Get a single environment by id. */
518
+ get(teamId: IdInput, projectId: IdInput, envId: IdInput): Promise<{
519
+ environment: Environment;
520
+ }>;
521
+ /** Create a new environment in the given project. */
522
+ create(teamId: IdInput, projectId: IdInput, data: CreateEnvironmentInput): Promise<{
523
+ environment: Environment;
524
+ }>;
525
+ /** Update environment metadata (name, default flag, protected flag). */
526
+ update(teamId: IdInput, projectId: IdInput, envId: IdInput, data: UpdateEnvironmentInput): Promise<{
527
+ environment: Environment;
528
+ }>;
529
+ /**
530
+ * Delete an environment. The API blocks delete when the env still
531
+ * has services or databases attached — destroy them first or move
532
+ * them to another env. Cannot delete the project's default env.
533
+ */
534
+ delete(teamId: IdInput, projectId: IdInput, envId: IdInput): Promise<void>;
535
+ }
536
+
404
537
  declare class EnvVarsResource {
405
538
  private client;
406
539
  constructor(client: HostStack);
@@ -422,6 +555,81 @@ declare class EnvVarsResource {
422
555
  bulkSet(teamId: IdInput, serviceId: IdInput, data: BulkSetEnvVarsInput): Promise<void>;
423
556
  }
424
557
 
558
+ type NotificationChannelType = 'slack' | 'discord' | 'email';
559
+ /**
560
+ * Events a notification channel can subscribe to. Source of truth is
561
+ * `packages/shared/src/schemas/notification-channel.ts:NOTIFICATION_CHANNEL_EVENTS`.
562
+ */
563
+ type NotificationChannelEvent = 'deploy.started' | 'deploy.succeeded' | 'deploy.failed' | 'deploy.failed_consecutive' | 'service.created' | 'service.deleted' | 'service.suspended' | 'service.resumed' | 'service.restart_failed' | 'service.auto_suspended' | 'service.acme_cert_failed' | 'git.auth_failed';
564
+ interface NotificationChannel {
565
+ id: number;
566
+ teamId: number;
567
+ type: NotificationChannelType;
568
+ name: string;
569
+ /**
570
+ * Webhook URL (Slack/Discord) or email address. The list API masks
571
+ * the value for security — only the create/update calls round-trip
572
+ * the real URL.
573
+ */
574
+ webhookUrl: string;
575
+ active: boolean;
576
+ events: NotificationChannelEvent[];
577
+ createdAt: string;
578
+ updatedAt: string;
579
+ }
580
+ declare class NotificationsResource {
581
+ private client;
582
+ constructor(client: HostStack);
583
+ /**
584
+ * List notification channels for the team. Webhook URLs are
585
+ * server-side masked in the response so this is safe to log.
586
+ */
587
+ listChannels(teamId: IdInput): Promise<{
588
+ channels: NotificationChannel[];
589
+ }>;
590
+ /**
591
+ * Create a Slack/Discord/email notification channel.
592
+ *
593
+ * For type=email, `webhookUrl` is the recipient email address; for
594
+ * type=slack/discord it's the incoming webhook URL.
595
+ *
596
+ * `events` is the explicit subscription list — an empty array means
597
+ * "receive nothing". The platform pre-selects the critical-event
598
+ * set on the dashboard, but SDK callers must pass the list
599
+ * explicitly so behaviour is deterministic.
600
+ */
601
+ createChannel(teamId: IdInput, data: {
602
+ type: NotificationChannelType;
603
+ name: string;
604
+ webhookUrl: string;
605
+ events: NotificationChannelEvent[];
606
+ }): Promise<{
607
+ channel: NotificationChannel;
608
+ }>;
609
+ /**
610
+ * Update a channel's name / active state / event subscriptions. The
611
+ * webhook URL and type are immutable — create a new channel if
612
+ * those need to change.
613
+ */
614
+ updateChannel(teamId: IdInput, channelId: number, data: {
615
+ name?: string;
616
+ active?: boolean;
617
+ events?: NotificationChannelEvent[];
618
+ }): Promise<{
619
+ channel: NotificationChannel;
620
+ }>;
621
+ /** Delete a notification channel. */
622
+ deleteChannel(teamId: IdInput, channelId: number): Promise<void>;
623
+ /**
624
+ * Fire a test event to the channel so the user can confirm the
625
+ * webhook is wired correctly. Returns the dispatch outcome.
626
+ */
627
+ testChannel(teamId: IdInput, channelId: number): Promise<{
628
+ success: boolean;
629
+ error?: string;
630
+ }>;
631
+ }
632
+
425
633
  declare class ProjectsResource {
426
634
  private client;
427
635
  constructor(client: HostStack);
@@ -447,8 +655,13 @@ declare class ProjectsResource {
447
655
 
448
656
  interface LogEntry$1 {
449
657
  timestamp: string;
450
- level?: string | null;
451
- stream?: string | null;
658
+ /**
659
+ * Parsed log level if the message is a structured JSON envelope
660
+ * (pino numeric, `{"level":"info"}`, or `{"severity":"WARNING"}`).
661
+ * `undefined` for plain-text logs.
662
+ */
663
+ level?: 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal' | null;
664
+ stream?: 'stdout' | 'stderr' | null;
452
665
  message: string;
453
666
  }
454
667
  interface StreamLogsOptions {
@@ -464,15 +677,30 @@ interface StreamLogsOptions {
464
677
 
465
678
  interface LogEntry {
466
679
  timestamp: string;
467
- level?: string | null;
468
- stream?: string | null;
680
+ /**
681
+ * Parsed structured log level (pino numeric or string envelopes).
682
+ * `undefined` for plain-text logs.
683
+ */
684
+ level?: 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal' | null;
685
+ stream?: 'stdout' | 'stderr' | null;
469
686
  message: string;
470
687
  }
471
688
  declare class ServicesResource {
472
689
  private client;
473
690
  constructor(client: HostStack);
474
- /** List all services for the active team. */
475
- list(teamId: IdInput): Promise<{
691
+ /**
692
+ * List services for the active team.
693
+ *
694
+ * Optional filters narrow by project, environment, status, or type.
695
+ * The server treats unknown enum values as no match (returns empty)
696
+ * rather than 400-ing.
697
+ */
698
+ list(teamId: IdInput, filters?: {
699
+ projectId?: number | string;
700
+ environmentId?: number | string;
701
+ status?: 'active' | 'deploying' | 'suspended' | 'failed' | 'not_deployed';
702
+ type?: 'web_service' | 'private_service' | 'worker' | 'cron_job' | 'static_site';
703
+ }): Promise<{
476
704
  services: Service[];
477
705
  }>;
478
706
  /** Get a single service by ID. */
@@ -497,6 +725,27 @@ declare class ServicesResource {
497
725
  getMetrics(teamId: IdInput, serviceId: IdInput): Promise<{
498
726
  metrics: ServiceMetrics;
499
727
  }>;
728
+ /**
729
+ * Get a metrics time series for a service.
730
+ *
731
+ * `from`/`to` accept ISO-8601 timestamps. Omit both for the trailing
732
+ * hour. Server picks the resolution: raw samples ≤7d, hourly pre-
733
+ * aggregates ≤30d, daily beyond that. Up to ~500 points returned.
734
+ */
735
+ getMetricsHistory(teamId: IdInput, serviceId: IdInput, options?: {
736
+ from?: string;
737
+ to?: string;
738
+ }): Promise<{
739
+ history: Array<{
740
+ timestamp: string;
741
+ cpuPercent: number;
742
+ memoryUsedMb: number;
743
+ memoryLimitMb: number;
744
+ networkRxBytes: number;
745
+ networkTxBytes: number;
746
+ diskUsedMb: number;
747
+ }>;
748
+ }>;
500
749
  /** Get service configuration. */
501
750
  getConfig(teamId: IdInput, serviceId: IdInput): Promise<{
502
751
  config: ServiceConfig;
@@ -505,13 +754,31 @@ declare class ServicesResource {
505
754
  updateConfig(teamId: IdInput, serviceId: IdInput, data: UpdateServiceConfigInput): Promise<{
506
755
  config: ServiceConfig;
507
756
  }>;
508
- /** Get runtime logs for a service. */
757
+ /**
758
+ * Get runtime logs for a service.
759
+ *
760
+ * `since`/`until` accept either an ISO-8601 timestamp or a short
761
+ * relative offset like `-5m`, `-1h`, `-2d`.
762
+ *
763
+ * `search` does case-insensitive substring filtering server-side
764
+ * (≤100 chars). `countOnly` returns just `{ count: N }` for cheap
765
+ * polling — useful when you want to know "how many error lines in the
766
+ * last 5 minutes" without paying the bytes.
767
+ */
509
768
  getRuntimeLogs(teamId: IdInput, serviceId: IdInput, options?: {
510
769
  lines?: number;
770
+ limit?: number;
511
771
  since?: string;
772
+ until?: string;
512
773
  stream?: 'stdout' | 'stderr';
774
+ level?: 'stdout' | 'stderr' | 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal';
775
+ search?: string;
776
+ grep?: string;
777
+ countOnly?: boolean;
513
778
  }): Promise<{
514
779
  logs: LogEntry[] | string;
780
+ } | {
781
+ count: number;
515
782
  }>;
516
783
  /**
517
784
  * Stream runtime logs for a service by polling the logs endpoint.
@@ -609,6 +876,9 @@ type ResolveScope = {
609
876
  kind: 'envVar';
610
877
  teamId: number;
611
878
  serviceId: number;
879
+ } | {
880
+ kind: 'environment';
881
+ teamId: number;
612
882
  } | {
613
883
  kind: 'cronExecution';
614
884
  teamId: number;
@@ -630,10 +900,18 @@ declare class HostStack {
630
900
  readonly domains: DomainsResource;
631
901
  /** Manage service environment variables. */
632
902
  readonly envVars: EnvVarsResource;
903
+ /** v66: manage environments (production/staging/development/preview) per project. */
904
+ readonly environments: EnvironmentsResource;
633
905
  /** Manage cron job executions. */
634
906
  readonly cron: CronResource;
635
907
  /** Manage persistent disks attached to services. */
636
908
  readonly volumes: VolumesResource;
909
+ /**
910
+ * Manage notification channels — Slack/Discord webhooks + email
911
+ * recipients with per-channel event filters. Used for deploy
912
+ * failures, restart loops, ACME failures, git auth losses, etc.
913
+ */
914
+ readonly notifications: NotificationsResource;
637
915
  constructor(options: HostStackOptions);
638
916
  /**
639
917
  * Make an authenticated request to the HostStack API.
@@ -697,4 +975,4 @@ declare function buildPaginationQuery(params?: PaginationParams): string;
697
975
  */
698
976
  declare function wrapArray<T>(items: T[], params?: PaginationParams): PaginatedResponse<T>;
699
977
 
700
- export { type ActivityLogEntry, type AddDomainInput, AuthenticationError, type BulkSetEnvVarsInput, type CreateDatabaseInput, type CreateEnvVarInput, type CreateProjectInput, type CreateServiceInput, type CronExecution, type Database, type DatabaseCredentials, type Deploy, type Domain, type EnvVar, HostStack, HostStackError, type HostStackOptions, type LogEntry$1 as LogEntry, type MeResponse, NotFoundError, 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 UpdateProjectInput, type UpdateServiceConfigInput, type UpdateServiceInput, type User, buildPaginationQuery, wrapArray };
978
+ 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 };