@hoststack.dev/sdk 0.4.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/README.md +17 -14
- package/dist/index.cjs +107 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +174 -9
- package/dist/index.d.ts +174 -9
- package/dist/index.js +107 -21
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -53,19 +53,21 @@ Generate an API key from your [HostStack dashboard → Settings → API Keys](ht
|
|
|
53
53
|
|
|
54
54
|
## Resources
|
|
55
55
|
|
|
56
|
-
| Resource
|
|
57
|
-
|
|
|
58
|
-
| `client.projects`
|
|
59
|
-
| `client.services`
|
|
60
|
-
| `client.deploys`
|
|
61
|
-
| `client.databases`
|
|
62
|
-
| `client.domains`
|
|
63
|
-
| `client.envVars`
|
|
64
|
-
| `client.
|
|
65
|
-
| `client.
|
|
66
|
-
| `client.
|
|
67
|
-
|
|
68
|
-
Every method's first argument is `
|
|
56
|
+
| Resource | Methods |
|
|
57
|
+
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
58
|
+
| `client.projects` | `list`, `get`, `create`, `update`, `delete` |
|
|
59
|
+
| `client.services` | `list`, `get`, `create`, `update`, `delete`, `suspend`, `resume`, `getMetrics`, `getConfig`, `updateConfig`, `getRuntimeLogs`, `streamLogs` |
|
|
60
|
+
| `client.deploys` | `list`, `get`, `trigger`, `cancel`, `rollback`, `promote`, `getLogs` |
|
|
61
|
+
| `client.databases` | `list`, `get`, `create`, `update`, `delete`, `suspend`, `resume`, `getCredentials`, `resetPassword` |
|
|
62
|
+
| `client.domains` | `list`, `add`, `update`, `remove`, `verify` |
|
|
63
|
+
| `client.envVars` | `list`, `create`, `update`, `delete`, `bulkSet` |
|
|
64
|
+
| `client.volumes` | `list`, `create`, `update`, `delete` |
|
|
65
|
+
| `client.environments` | `list`, `get`, `create`, `update`, `delete` |
|
|
66
|
+
| `client.cron` | `list`, `get`, `trigger` |
|
|
67
|
+
|
|
68
|
+
Every method's first argument is the team id — accepts either the numeric id or the `team_…` publicId (the SDK resolves publicIds to numeric ids internally and caches the lookup). Full API reference: **[hoststack.dev/docs/sdk](https://hoststack.dev/docs/sdk)**.
|
|
69
|
+
|
|
70
|
+
`client.deploys.promote(teamId, serviceId, deployId, targetEnvironmentId)` performs image-based promotion: it pins the same built image into a sibling environment without rebuilding.
|
|
69
71
|
|
|
70
72
|
## Error handling
|
|
71
73
|
|
|
@@ -96,7 +98,8 @@ try {
|
|
|
96
98
|
## Related packages
|
|
97
99
|
|
|
98
100
|
- **[@hoststack.dev/cli](https://www.npmjs.com/package/@hoststack.dev/cli)** — command-line interface for HostStack
|
|
99
|
-
- **[
|
|
101
|
+
- **[@hoststack.dev/mcp](https://www.npmjs.com/package/@hoststack.dev/mcp)** — MCP server for Claude, Cursor, and other AI agents
|
|
102
|
+
- **Terraform provider** — see [hoststack.dev/docs](https://hoststack.dev/docs) for installation and resource reference
|
|
100
103
|
|
|
101
104
|
## Support
|
|
102
105
|
|
package/dist/index.cjs
CHANGED
|
@@ -198,11 +198,9 @@ var DeploysResource = class {
|
|
|
198
198
|
teamId: tid,
|
|
199
199
|
serviceId: sid
|
|
200
200
|
});
|
|
201
|
-
return this.client.request(
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
{ targetEnvironmentId }
|
|
205
|
-
);
|
|
201
|
+
return this.client.request("POST", `/api/services/${tid}/${sid}/deploys/${did}/promote`, {
|
|
202
|
+
targetEnvironmentId
|
|
203
|
+
});
|
|
206
204
|
}
|
|
207
205
|
/**
|
|
208
206
|
* Get build logs for a deploy.
|
|
@@ -356,6 +354,65 @@ var EnvVarsResource = class {
|
|
|
356
354
|
}
|
|
357
355
|
};
|
|
358
356
|
|
|
357
|
+
// src/resources/notifications.ts
|
|
358
|
+
var NotificationsResource = class {
|
|
359
|
+
constructor(client) {
|
|
360
|
+
this.client = client;
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* List notification channels for the team. Webhook URLs are
|
|
364
|
+
* server-side masked in the response so this is safe to log.
|
|
365
|
+
*/
|
|
366
|
+
async listChannels(teamId) {
|
|
367
|
+
const tid = await this.client.resolveId(teamId, { kind: "team" });
|
|
368
|
+
return this.client.request("GET", `/api/notifications/${tid}/channels`);
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* Create a Slack/Discord/email notification channel.
|
|
372
|
+
*
|
|
373
|
+
* For type=email, `webhookUrl` is the recipient email address; for
|
|
374
|
+
* type=slack/discord it's the incoming webhook URL.
|
|
375
|
+
*
|
|
376
|
+
* `events` is the explicit subscription list — an empty array means
|
|
377
|
+
* "receive nothing". The platform pre-selects the critical-event
|
|
378
|
+
* set on the dashboard, but SDK callers must pass the list
|
|
379
|
+
* explicitly so behaviour is deterministic.
|
|
380
|
+
*/
|
|
381
|
+
async createChannel(teamId, data) {
|
|
382
|
+
const tid = await this.client.resolveId(teamId, { kind: "team" });
|
|
383
|
+
return this.client.request("POST", `/api/notifications/${tid}/channels`, data);
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Update a channel's name / active state / event subscriptions. The
|
|
387
|
+
* webhook URL and type are immutable — create a new channel if
|
|
388
|
+
* those need to change.
|
|
389
|
+
*/
|
|
390
|
+
async updateChannel(teamId, channelId, data) {
|
|
391
|
+
const tid = await this.client.resolveId(teamId, { kind: "team" });
|
|
392
|
+
return this.client.request(
|
|
393
|
+
"PATCH",
|
|
394
|
+
`/api/notifications/${tid}/channels/${channelId}`,
|
|
395
|
+
data
|
|
396
|
+
);
|
|
397
|
+
}
|
|
398
|
+
/** Delete a notification channel. */
|
|
399
|
+
async deleteChannel(teamId, channelId) {
|
|
400
|
+
const tid = await this.client.resolveId(teamId, { kind: "team" });
|
|
401
|
+
return this.client.request("DELETE", `/api/notifications/${tid}/channels/${channelId}`);
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* Fire a test event to the channel so the user can confirm the
|
|
405
|
+
* webhook is wired correctly. Returns the dispatch outcome.
|
|
406
|
+
*/
|
|
407
|
+
async testChannel(teamId, channelId) {
|
|
408
|
+
const tid = await this.client.resolveId(teamId, { kind: "team" });
|
|
409
|
+
return this.client.request(
|
|
410
|
+
"POST",
|
|
411
|
+
`/api/notifications/${tid}/channels/${channelId}/test`
|
|
412
|
+
);
|
|
413
|
+
}
|
|
414
|
+
};
|
|
415
|
+
|
|
359
416
|
// src/resources/projects.ts
|
|
360
417
|
var ProjectsResource = class {
|
|
361
418
|
constructor(client) {
|
|
@@ -453,10 +510,23 @@ var ServicesResource = class {
|
|
|
453
510
|
constructor(client) {
|
|
454
511
|
this.client = client;
|
|
455
512
|
}
|
|
456
|
-
/**
|
|
457
|
-
|
|
513
|
+
/**
|
|
514
|
+
* List services for the active team.
|
|
515
|
+
*
|
|
516
|
+
* Optional filters narrow by project, environment, status, or type.
|
|
517
|
+
* The server treats unknown enum values as no match (returns empty)
|
|
518
|
+
* rather than 400-ing.
|
|
519
|
+
*/
|
|
520
|
+
async list(teamId, filters) {
|
|
458
521
|
const tid = await this.client.resolveId(teamId, { kind: "team" });
|
|
459
|
-
|
|
522
|
+
const params = new URLSearchParams();
|
|
523
|
+
if (filters?.projectId !== void 0) params.set("projectId", String(filters.projectId));
|
|
524
|
+
if (filters?.environmentId !== void 0)
|
|
525
|
+
params.set("environmentId", String(filters.environmentId));
|
|
526
|
+
if (filters?.status) params.set("status", filters.status);
|
|
527
|
+
if (filters?.type) params.set("type", filters.type);
|
|
528
|
+
const qs = params.toString();
|
|
529
|
+
return this.client.request("GET", `/api/services/${tid}${qs ? `?${qs}` : ""}`);
|
|
460
530
|
}
|
|
461
531
|
/** Get a single service by ID. */
|
|
462
532
|
async get(teamId, serviceId) {
|
|
@@ -499,6 +569,25 @@ var ServicesResource = class {
|
|
|
499
569
|
const sid = await this.client.resolveId(serviceId, { kind: "service", teamId: tid });
|
|
500
570
|
return this.client.request("GET", `/api/services/${tid}/${sid}/metrics`);
|
|
501
571
|
}
|
|
572
|
+
/**
|
|
573
|
+
* Get a metrics time series for a service.
|
|
574
|
+
*
|
|
575
|
+
* `from`/`to` accept ISO-8601 timestamps. Omit both for the trailing
|
|
576
|
+
* hour. Server picks the resolution: raw samples ≤7d, hourly pre-
|
|
577
|
+
* aggregates ≤30d, daily beyond that. Up to ~500 points returned.
|
|
578
|
+
*/
|
|
579
|
+
async getMetricsHistory(teamId, serviceId, options) {
|
|
580
|
+
const tid = await this.client.resolveId(teamId, { kind: "team" });
|
|
581
|
+
const sid = await this.client.resolveId(serviceId, { kind: "service", teamId: tid });
|
|
582
|
+
const params = new URLSearchParams();
|
|
583
|
+
if (options?.from) params.set("from", options.from);
|
|
584
|
+
if (options?.to) params.set("to", options.to);
|
|
585
|
+
const qs = params.toString();
|
|
586
|
+
return this.client.request(
|
|
587
|
+
"GET",
|
|
588
|
+
`/api/services/${tid}/${sid}/metrics/history${qs ? `?${qs}` : ""}`
|
|
589
|
+
);
|
|
590
|
+
}
|
|
502
591
|
/** Get service configuration. */
|
|
503
592
|
async getConfig(teamId, serviceId) {
|
|
504
593
|
const tid = await this.client.resolveId(teamId, { kind: "team" });
|
|
@@ -557,11 +646,7 @@ var ServicesResource = class {
|
|
|
557
646
|
const tid = await this.client.resolveId(teamId, { kind: "team" });
|
|
558
647
|
const sid = await this.client.resolveId(serviceId, { kind: "service", teamId: tid });
|
|
559
648
|
const basePath = `/api/services/${tid}/${sid}/runtime-logs`;
|
|
560
|
-
yield* streamLogsViaPolling(
|
|
561
|
-
(path) => this.client.request("GET", path),
|
|
562
|
-
basePath,
|
|
563
|
-
options
|
|
564
|
-
);
|
|
649
|
+
yield* streamLogsViaPolling((path) => this.client.request("GET", path), basePath, options);
|
|
565
650
|
}
|
|
566
651
|
};
|
|
567
652
|
|
|
@@ -649,6 +734,12 @@ var HostStack = class {
|
|
|
649
734
|
cron;
|
|
650
735
|
/** Manage persistent disks attached to services. */
|
|
651
736
|
volumes;
|
|
737
|
+
/**
|
|
738
|
+
* Manage notification channels — Slack/Discord webhooks + email
|
|
739
|
+
* recipients with per-channel event filters. Used for deploy
|
|
740
|
+
* failures, restart loops, ACME failures, git auth losses, etc.
|
|
741
|
+
*/
|
|
742
|
+
notifications;
|
|
652
743
|
constructor(options) {
|
|
653
744
|
if (!options.apiKey) {
|
|
654
745
|
throw new Error("apiKey is required");
|
|
@@ -664,6 +755,7 @@ var HostStack = class {
|
|
|
664
755
|
this.environments = new EnvironmentsResource(this);
|
|
665
756
|
this.cron = new CronResource(this);
|
|
666
757
|
this.volumes = new VolumesResource(this);
|
|
758
|
+
this.notifications = new NotificationsResource(this);
|
|
667
759
|
}
|
|
668
760
|
/**
|
|
669
761
|
* Make an authenticated request to the HostStack API.
|
|
@@ -755,17 +847,11 @@ var HostStack = class {
|
|
|
755
847
|
return r.services ?? [];
|
|
756
848
|
}
|
|
757
849
|
case "deploy": {
|
|
758
|
-
const r = await this.request(
|
|
759
|
-
"GET",
|
|
760
|
-
`/api/services/${scope.teamId}/${scope.serviceId}/deploys?perPage=100`
|
|
761
|
-
);
|
|
850
|
+
const r = await this.request("GET", `/api/services/${scope.teamId}/${scope.serviceId}/deploys?perPage=100`);
|
|
762
851
|
return r.data ?? [];
|
|
763
852
|
}
|
|
764
853
|
case "database": {
|
|
765
|
-
const r = await this.request(
|
|
766
|
-
"GET",
|
|
767
|
-
`/api/databases/${scope.teamId}`
|
|
768
|
-
);
|
|
854
|
+
const r = await this.request("GET", `/api/databases/${scope.teamId}`);
|
|
769
855
|
return r.databases ?? [];
|
|
770
856
|
}
|
|
771
857
|
case "domain": {
|