@sota-io/sdk 1.0.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/LICENSE +21 -0
- package/README.md +320 -0
- package/dist/client.d.ts +118 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +271 -0
- package/dist/client.js.map +1 -0
- package/dist/errors.d.ts +21 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +29 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +84 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/package.json +39 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 sota.io
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
# @sota-io/sdk
|
|
2
|
+
|
|
3
|
+
TypeScript SDK for the [sota.io](https://sota.io) deployment platform.
|
|
4
|
+
Deploy web apps, manage projects, and control deployments programmatically.
|
|
5
|
+
|
|
6
|
+
[](https://www.npmjs.com/package/@sota-io/sdk)
|
|
7
|
+
[](LICENSE)
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @sota-io/sdk
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
Deploy an app in 5 lines:
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import { SotaClient } from '@sota-io/sdk';
|
|
21
|
+
import { readFileSync } from 'fs';
|
|
22
|
+
|
|
23
|
+
const sota = new SotaClient({ apiKey: 'sota_your_api_key' });
|
|
24
|
+
const project = await sota.createProject({ name: 'my-app' });
|
|
25
|
+
const deployment = await sota.deploy(project.id, readFileSync('app.tar.gz'));
|
|
26
|
+
console.log(`Live at: ${deployment.url}`);
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Authentication
|
|
30
|
+
|
|
31
|
+
Get your API key from the [sota.io dashboard](https://sota.io/dashboard) or via the CLI:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
sota auth set-key <your-api-key>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Create a client with your key:
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
import { SotaClient } from '@sota-io/sdk';
|
|
41
|
+
|
|
42
|
+
const sota = new SotaClient({ apiKey: 'sota_your_api_key' });
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
For self-hosted or staging environments, pass a custom base URL:
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
const sota = new SotaClient({
|
|
49
|
+
apiKey: 'sota_your_api_key',
|
|
50
|
+
baseUrl: 'https://api.staging.sota.io',
|
|
51
|
+
});
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## API Reference
|
|
55
|
+
|
|
56
|
+
### Projects
|
|
57
|
+
|
|
58
|
+
### client.listProjects(options?)
|
|
59
|
+
|
|
60
|
+
List all projects for the authenticated user.
|
|
61
|
+
|
|
62
|
+
**Parameters:**
|
|
63
|
+
- `options.cursor` (string, optional) -- Pagination cursor from a previous response
|
|
64
|
+
- `options.limit` (number, optional) -- Maximum number of projects to return
|
|
65
|
+
|
|
66
|
+
**Returns:** `Promise<{ projects: Project[]; pagination?: Pagination }>`
|
|
67
|
+
|
|
68
|
+
**Example:**
|
|
69
|
+
```typescript
|
|
70
|
+
const { projects, pagination } = await sota.listProjects({ limit: 10 });
|
|
71
|
+
console.log(projects.map(p => p.name));
|
|
72
|
+
|
|
73
|
+
// Paginate
|
|
74
|
+
if (pagination?.has_more) {
|
|
75
|
+
const next = await sota.listProjects({ cursor: pagination.next_cursor });
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### client.createProject(options)
|
|
80
|
+
|
|
81
|
+
Create a new project. The slug is auto-generated from the name if not provided.
|
|
82
|
+
|
|
83
|
+
**Parameters:**
|
|
84
|
+
- `options.name` (string) -- Human-readable project name
|
|
85
|
+
- `options.slug` (string, optional) -- URL-safe slug (auto-generated if omitted)
|
|
86
|
+
|
|
87
|
+
**Returns:** `Promise<Project>`
|
|
88
|
+
|
|
89
|
+
**Example:**
|
|
90
|
+
```typescript
|
|
91
|
+
const project = await sota.createProject({ name: 'My Cool App' });
|
|
92
|
+
console.log(project.slug); // "my-cool-app"
|
|
93
|
+
console.log(project.id); // UUID
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### client.getProject(projectId)
|
|
97
|
+
|
|
98
|
+
Get a project by ID.
|
|
99
|
+
|
|
100
|
+
**Parameters:**
|
|
101
|
+
- `projectId` (string) -- The project UUID
|
|
102
|
+
|
|
103
|
+
**Returns:** `Promise<Project>`
|
|
104
|
+
|
|
105
|
+
**Example:**
|
|
106
|
+
```typescript
|
|
107
|
+
const project = await sota.getProject('abc-123-def');
|
|
108
|
+
console.log(project.name, project.slug);
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### client.deleteProject(projectId)
|
|
112
|
+
|
|
113
|
+
Delete a project and all its deployments.
|
|
114
|
+
|
|
115
|
+
**Parameters:**
|
|
116
|
+
- `projectId` (string) -- The project UUID
|
|
117
|
+
|
|
118
|
+
**Returns:** `Promise<void>`
|
|
119
|
+
|
|
120
|
+
**Example:**
|
|
121
|
+
```typescript
|
|
122
|
+
await sota.deleteProject('abc-123-def');
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Deployments
|
|
126
|
+
|
|
127
|
+
### client.deploy(projectId, archive)
|
|
128
|
+
|
|
129
|
+
Deploy an app from a tar.gz archive. The archive should contain your application source code.
|
|
130
|
+
|
|
131
|
+
**Parameters:**
|
|
132
|
+
- `projectId` (string) -- The project UUID
|
|
133
|
+
- `archive` (Buffer | Uint8Array) -- The tar.gz archive
|
|
134
|
+
|
|
135
|
+
**Returns:** `Promise<Deployment>`
|
|
136
|
+
|
|
137
|
+
**Example:**
|
|
138
|
+
```typescript
|
|
139
|
+
import { readFileSync } from 'fs';
|
|
140
|
+
|
|
141
|
+
const archive = readFileSync('app.tar.gz');
|
|
142
|
+
const deployment = await sota.deploy(project.id, archive);
|
|
143
|
+
console.log(`Status: ${deployment.status}`);
|
|
144
|
+
console.log(`URL: ${deployment.url}`);
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### client.listDeployments(projectId)
|
|
148
|
+
|
|
149
|
+
List all deployments for a project, most recent first.
|
|
150
|
+
|
|
151
|
+
**Parameters:**
|
|
152
|
+
- `projectId` (string) -- The project UUID
|
|
153
|
+
|
|
154
|
+
**Returns:** `Promise<Deployment[]>`
|
|
155
|
+
|
|
156
|
+
**Example:**
|
|
157
|
+
```typescript
|
|
158
|
+
const deployments = await sota.listDeployments(project.id);
|
|
159
|
+
const latest = deployments[0];
|
|
160
|
+
console.log(`Latest: ${latest.status} at ${latest.url}`);
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### client.getLogs(projectId, deploymentId)
|
|
164
|
+
|
|
165
|
+
Get build and runtime logs for a specific deployment.
|
|
166
|
+
|
|
167
|
+
**Parameters:**
|
|
168
|
+
- `projectId` (string) -- The project UUID
|
|
169
|
+
- `deploymentId` (string) -- The deployment UUID
|
|
170
|
+
|
|
171
|
+
**Returns:** `Promise<string>` -- Raw log text
|
|
172
|
+
|
|
173
|
+
**Example:**
|
|
174
|
+
```typescript
|
|
175
|
+
const logs = await sota.getLogs(project.id, deployment.id);
|
|
176
|
+
console.log(logs);
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### client.rollback(projectId)
|
|
180
|
+
|
|
181
|
+
Rollback to the previous deployment. Restores the prior container without rebuilding.
|
|
182
|
+
|
|
183
|
+
**Parameters:**
|
|
184
|
+
- `projectId` (string) -- The project UUID
|
|
185
|
+
|
|
186
|
+
**Returns:** `Promise<Deployment>`
|
|
187
|
+
|
|
188
|
+
**Example:**
|
|
189
|
+
```typescript
|
|
190
|
+
const restored = await sota.rollback(project.id);
|
|
191
|
+
console.log(`Rolled back to: ${restored.url}`);
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### client.redeploy(projectId)
|
|
195
|
+
|
|
196
|
+
Redeploy the latest deployment. Rebuilds and deploys the most recent source.
|
|
197
|
+
|
|
198
|
+
**Parameters:**
|
|
199
|
+
- `projectId` (string) -- The project UUID
|
|
200
|
+
|
|
201
|
+
**Returns:** `Promise<Deployment>`
|
|
202
|
+
|
|
203
|
+
**Example:**
|
|
204
|
+
```typescript
|
|
205
|
+
const deployment = await sota.redeploy(project.id);
|
|
206
|
+
console.log(`Redeployed: ${deployment.status}`);
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Environment Variables
|
|
210
|
+
|
|
211
|
+
### client.listEnvVars(projectId)
|
|
212
|
+
|
|
213
|
+
List all environment variables for a project.
|
|
214
|
+
|
|
215
|
+
**Parameters:**
|
|
216
|
+
- `projectId` (string) -- The project UUID
|
|
217
|
+
|
|
218
|
+
**Returns:** `Promise<EnvVar[]>`
|
|
219
|
+
|
|
220
|
+
**Example:**
|
|
221
|
+
```typescript
|
|
222
|
+
const envVars = await sota.listEnvVars(project.id);
|
|
223
|
+
envVars.forEach(v => console.log(`${v.key}=${v.value}`));
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### client.setEnvVar(projectId, options)
|
|
227
|
+
|
|
228
|
+
Set an environment variable. Creates it if new, updates it if it already exists.
|
|
229
|
+
|
|
230
|
+
**Parameters:**
|
|
231
|
+
- `projectId` (string) -- The project UUID
|
|
232
|
+
- `options.key` (string) -- Variable name
|
|
233
|
+
- `options.value` (string) -- Variable value
|
|
234
|
+
|
|
235
|
+
**Returns:** `Promise<void>`
|
|
236
|
+
|
|
237
|
+
**Example:**
|
|
238
|
+
```typescript
|
|
239
|
+
await sota.setEnvVar(project.id, {
|
|
240
|
+
key: 'DATABASE_URL',
|
|
241
|
+
value: 'postgres://localhost:5432/mydb',
|
|
242
|
+
});
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### client.deleteEnvVar(projectId, key)
|
|
246
|
+
|
|
247
|
+
Delete an environment variable from a project.
|
|
248
|
+
|
|
249
|
+
**Parameters:**
|
|
250
|
+
- `projectId` (string) -- The project UUID
|
|
251
|
+
- `key` (string) -- The variable name to delete
|
|
252
|
+
|
|
253
|
+
**Returns:** `Promise<void>`
|
|
254
|
+
|
|
255
|
+
**Example:**
|
|
256
|
+
```typescript
|
|
257
|
+
await sota.deleteEnvVar(project.id, 'OLD_VARIABLE');
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
## Error Handling
|
|
261
|
+
|
|
262
|
+
All API errors are thrown as `SotaAPIError` instances with the HTTP status code, a machine-readable error code, and a human-readable message:
|
|
263
|
+
|
|
264
|
+
```typescript
|
|
265
|
+
import { SotaClient, SotaAPIError } from '@sota-io/sdk';
|
|
266
|
+
|
|
267
|
+
const sota = new SotaClient({ apiKey: 'sota_your_api_key' });
|
|
268
|
+
|
|
269
|
+
try {
|
|
270
|
+
await sota.getProject('non-existent-id');
|
|
271
|
+
} catch (err) {
|
|
272
|
+
if (err instanceof SotaAPIError) {
|
|
273
|
+
console.error(`HTTP ${err.statusCode}: [${err.code}] ${err.message}`);
|
|
274
|
+
// e.g. "HTTP 404: [not_found] Project not found"
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
## TypeScript Types
|
|
280
|
+
|
|
281
|
+
All types are exported for use in your application:
|
|
282
|
+
|
|
283
|
+
```typescript
|
|
284
|
+
import type {
|
|
285
|
+
Project,
|
|
286
|
+
Deployment,
|
|
287
|
+
EnvVar,
|
|
288
|
+
SotaClientOptions,
|
|
289
|
+
CreateProjectOptions,
|
|
290
|
+
SetEnvVarOptions,
|
|
291
|
+
ListOptions,
|
|
292
|
+
Pagination,
|
|
293
|
+
DataResponse,
|
|
294
|
+
ListResponse,
|
|
295
|
+
APIErrorBody,
|
|
296
|
+
} from '@sota-io/sdk';
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
| Type | Description |
|
|
300
|
+
|------|-------------|
|
|
301
|
+
| `Project` | A sota.io project with id, name, slug, timestamps |
|
|
302
|
+
| `Deployment` | A deployment with status, url, build info, timestamps |
|
|
303
|
+
| `EnvVar` | An environment variable with key, value, timestamps |
|
|
304
|
+
| `SotaClientOptions` | Constructor options: apiKey (required), baseUrl (optional) |
|
|
305
|
+
| `CreateProjectOptions` | Project creation: name (required), slug (optional) |
|
|
306
|
+
| `SetEnvVarOptions` | Env var: key and value |
|
|
307
|
+
| `ListOptions` | Pagination: cursor and limit |
|
|
308
|
+
| `Pagination` | Pagination metadata: next_cursor, has_more |
|
|
309
|
+
| `DataResponse<T>` | API envelope for single items |
|
|
310
|
+
| `ListResponse<T>` | API envelope for lists with pagination |
|
|
311
|
+
| `APIErrorBody` | API error response body |
|
|
312
|
+
|
|
313
|
+
## Requirements
|
|
314
|
+
|
|
315
|
+
- **Node.js >= 18** (uses native `fetch`)
|
|
316
|
+
- **sota.io API key** -- get one at [sota.io/dashboard](https://sota.io/dashboard)
|
|
317
|
+
|
|
318
|
+
## License
|
|
319
|
+
|
|
320
|
+
MIT
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main client class for the sota.io API.
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* ```typescript
|
|
6
|
+
* import { SotaClient } from '@sota-io/sdk';
|
|
7
|
+
*
|
|
8
|
+
* const sota = new SotaClient({ apiKey: 'sota_your_api_key' });
|
|
9
|
+
* const projects = await sota.listProjects();
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
12
|
+
import type { SotaClientOptions, Project, Deployment, EnvVar, CreateProjectOptions, SetEnvVarOptions, ListOptions, Pagination } from './types.js';
|
|
13
|
+
export declare class SotaClient {
|
|
14
|
+
private readonly apiKey;
|
|
15
|
+
private readonly baseUrl;
|
|
16
|
+
/**
|
|
17
|
+
* Create a new SotaClient.
|
|
18
|
+
*
|
|
19
|
+
* @param options - Client configuration. `apiKey` is required.
|
|
20
|
+
*/
|
|
21
|
+
constructor(options: SotaClientOptions);
|
|
22
|
+
/**
|
|
23
|
+
* Generic JSON request helper. Handles auth headers, JSON serialization,
|
|
24
|
+
* and error mapping.
|
|
25
|
+
*/
|
|
26
|
+
private request;
|
|
27
|
+
/**
|
|
28
|
+
* List all projects for the authenticated user.
|
|
29
|
+
*
|
|
30
|
+
* @param options - Optional pagination parameters.
|
|
31
|
+
* @returns An object containing the projects array and optional pagination metadata.
|
|
32
|
+
*/
|
|
33
|
+
listProjects(options?: ListOptions): Promise<{
|
|
34
|
+
projects: Project[];
|
|
35
|
+
pagination?: Pagination;
|
|
36
|
+
}>;
|
|
37
|
+
/**
|
|
38
|
+
* Create a new project.
|
|
39
|
+
*
|
|
40
|
+
* @param options - Project creation options. `name` is required; `slug` is auto-generated if omitted.
|
|
41
|
+
* @returns The created project.
|
|
42
|
+
*/
|
|
43
|
+
createProject(options: CreateProjectOptions): Promise<Project>;
|
|
44
|
+
/**
|
|
45
|
+
* Get a project by ID.
|
|
46
|
+
*
|
|
47
|
+
* @param projectId - The project UUID.
|
|
48
|
+
* @returns The project details.
|
|
49
|
+
*/
|
|
50
|
+
getProject(projectId: string): Promise<Project>;
|
|
51
|
+
/**
|
|
52
|
+
* Delete a project.
|
|
53
|
+
*
|
|
54
|
+
* @param projectId - The project UUID.
|
|
55
|
+
*/
|
|
56
|
+
deleteProject(projectId: string): Promise<void>;
|
|
57
|
+
/**
|
|
58
|
+
* Deploy a project from a tar.gz archive.
|
|
59
|
+
*
|
|
60
|
+
* @param projectId - The project UUID.
|
|
61
|
+
* @param archive - The tar.gz archive as a `Buffer` or `Uint8Array`.
|
|
62
|
+
* @returns The created deployment.
|
|
63
|
+
*/
|
|
64
|
+
deploy(projectId: string, archive: Buffer | Uint8Array): Promise<Deployment>;
|
|
65
|
+
/**
|
|
66
|
+
* List all deployments for a project.
|
|
67
|
+
*
|
|
68
|
+
* @param projectId - The project UUID.
|
|
69
|
+
* @returns An array of deployments, most recent first.
|
|
70
|
+
*/
|
|
71
|
+
listDeployments(projectId: string): Promise<Deployment[]>;
|
|
72
|
+
/**
|
|
73
|
+
* Get build/runtime logs for a specific deployment.
|
|
74
|
+
*
|
|
75
|
+
* @param projectId - The project UUID.
|
|
76
|
+
* @param deploymentId - The deployment UUID.
|
|
77
|
+
* @returns The raw log text.
|
|
78
|
+
*/
|
|
79
|
+
getLogs(projectId: string, deploymentId: string): Promise<string>;
|
|
80
|
+
/**
|
|
81
|
+
* Rollback to the previous deployment.
|
|
82
|
+
*
|
|
83
|
+
* @param projectId - The project UUID.
|
|
84
|
+
* @returns The restored deployment.
|
|
85
|
+
*/
|
|
86
|
+
rollback(projectId: string): Promise<Deployment>;
|
|
87
|
+
/**
|
|
88
|
+
* Redeploy the latest deployment.
|
|
89
|
+
*
|
|
90
|
+
* @param projectId - The project UUID.
|
|
91
|
+
* @returns The new deployment.
|
|
92
|
+
*/
|
|
93
|
+
redeploy(projectId: string): Promise<Deployment>;
|
|
94
|
+
/**
|
|
95
|
+
* List all environment variables for a project.
|
|
96
|
+
*
|
|
97
|
+
* @param projectId - The project UUID.
|
|
98
|
+
* @returns An array of environment variables.
|
|
99
|
+
*/
|
|
100
|
+
listEnvVars(projectId: string): Promise<EnvVar[]>;
|
|
101
|
+
/**
|
|
102
|
+
* Set an environment variable on a project.
|
|
103
|
+
*
|
|
104
|
+
* Creates the variable if it doesn't exist, or updates it if it does.
|
|
105
|
+
*
|
|
106
|
+
* @param projectId - The project UUID.
|
|
107
|
+
* @param options - The key/value pair to set.
|
|
108
|
+
*/
|
|
109
|
+
setEnvVar(projectId: string, options: SetEnvVarOptions): Promise<void>;
|
|
110
|
+
/**
|
|
111
|
+
* Delete an environment variable from a project.
|
|
112
|
+
*
|
|
113
|
+
* @param projectId - The project UUID.
|
|
114
|
+
* @param key - The variable name to delete.
|
|
115
|
+
*/
|
|
116
|
+
deleteEnvVar(projectId: string, key: string): Promise<void>;
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EACV,iBAAiB,EACjB,OAAO,EACP,UAAU,EACV,MAAM,EAIN,oBAAoB,EACpB,gBAAgB,EAChB,WAAW,EACX,UAAU,EACX,MAAM,YAAY,CAAC;AAKpB,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IAEjC;;;;OAIG;gBACS,OAAO,EAAE,iBAAiB;IAStC;;;OAGG;YACW,OAAO;IA6CrB;;;;;OAKG;IACG,YAAY,CAChB,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC;QAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;QAAC,UAAU,CAAC,EAAE,UAAU,CAAA;KAAE,CAAC;IAW5D;;;;;OAKG;IACG,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,OAAO,CAAC;IASpE;;;;;OAKG;IACG,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAQrD;;;;OAIG;IACG,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA2BrD;;;;;;OAMG;IACG,MAAM,CACV,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GAAG,UAAU,GAC3B,OAAO,CAAC,UAAU,CAAC;IAsDtB;;;;;OAKG;IACG,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAQ/D;;;;;;OAMG;IACG,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA2BvE;;;;;OAKG;IACG,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAQtD;;;;;OAKG;IACG,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAYtD;;;;;OAKG;IACG,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAQvD;;;;;;;OAOG;IACG,SAAS,CACb,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,IAAI,CAAC;IAQhB;;;;;OAKG;IACG,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAsBlE"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main client class for the sota.io API.
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* ```typescript
|
|
6
|
+
* import { SotaClient } from '@sota-io/sdk';
|
|
7
|
+
*
|
|
8
|
+
* const sota = new SotaClient({ apiKey: 'sota_your_api_key' });
|
|
9
|
+
* const projects = await sota.listProjects();
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
12
|
+
import { SotaAPIError } from './errors.js';
|
|
13
|
+
const DEFAULT_BASE_URL = 'https://api.sota.io';
|
|
14
|
+
export class SotaClient {
|
|
15
|
+
apiKey;
|
|
16
|
+
baseUrl;
|
|
17
|
+
/**
|
|
18
|
+
* Create a new SotaClient.
|
|
19
|
+
*
|
|
20
|
+
* @param options - Client configuration. `apiKey` is required.
|
|
21
|
+
*/
|
|
22
|
+
constructor(options) {
|
|
23
|
+
this.apiKey = options.apiKey;
|
|
24
|
+
this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/$/, '');
|
|
25
|
+
}
|
|
26
|
+
// -------------------------------------------------------------------------
|
|
27
|
+
// Private helpers
|
|
28
|
+
// -------------------------------------------------------------------------
|
|
29
|
+
/**
|
|
30
|
+
* Generic JSON request helper. Handles auth headers, JSON serialization,
|
|
31
|
+
* and error mapping.
|
|
32
|
+
*/
|
|
33
|
+
async request(method, path, body) {
|
|
34
|
+
const url = `${this.baseUrl}${path}`;
|
|
35
|
+
const headers = {
|
|
36
|
+
'Authorization': `Bearer ${this.apiKey}`,
|
|
37
|
+
};
|
|
38
|
+
if (body !== undefined) {
|
|
39
|
+
headers['Content-Type'] = 'application/json';
|
|
40
|
+
}
|
|
41
|
+
const response = await fetch(url, {
|
|
42
|
+
method,
|
|
43
|
+
headers,
|
|
44
|
+
body: body !== undefined ? JSON.stringify(body) : undefined,
|
|
45
|
+
});
|
|
46
|
+
if (!response.ok) {
|
|
47
|
+
let errorBody;
|
|
48
|
+
try {
|
|
49
|
+
errorBody = (await response.json());
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
// response body may not be JSON
|
|
53
|
+
}
|
|
54
|
+
throw new SotaAPIError(response.status, errorBody?.error?.code ?? 'unknown', errorBody?.error?.message ?? response.statusText);
|
|
55
|
+
}
|
|
56
|
+
// Handle 204 No Content (DELETE responses)
|
|
57
|
+
if (response.status === 204) {
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
return response.json();
|
|
61
|
+
}
|
|
62
|
+
// -------------------------------------------------------------------------
|
|
63
|
+
// Projects
|
|
64
|
+
// -------------------------------------------------------------------------
|
|
65
|
+
/**
|
|
66
|
+
* List all projects for the authenticated user.
|
|
67
|
+
*
|
|
68
|
+
* @param options - Optional pagination parameters.
|
|
69
|
+
* @returns An object containing the projects array and optional pagination metadata.
|
|
70
|
+
*/
|
|
71
|
+
async listProjects(options) {
|
|
72
|
+
const params = new URLSearchParams();
|
|
73
|
+
if (options?.cursor)
|
|
74
|
+
params.set('cursor', options.cursor);
|
|
75
|
+
if (options?.limit)
|
|
76
|
+
params.set('limit', String(options.limit));
|
|
77
|
+
const qs = params.toString();
|
|
78
|
+
const path = `/v1/projects${qs ? `?${qs}` : ''}`;
|
|
79
|
+
const resp = await this.request('GET', path);
|
|
80
|
+
return { projects: resp.data, pagination: resp.pagination };
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Create a new project.
|
|
84
|
+
*
|
|
85
|
+
* @param options - Project creation options. `name` is required; `slug` is auto-generated if omitted.
|
|
86
|
+
* @returns The created project.
|
|
87
|
+
*/
|
|
88
|
+
async createProject(options) {
|
|
89
|
+
const resp = await this.request('POST', '/v1/projects', options);
|
|
90
|
+
return resp.data;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Get a project by ID.
|
|
94
|
+
*
|
|
95
|
+
* @param projectId - The project UUID.
|
|
96
|
+
* @returns The project details.
|
|
97
|
+
*/
|
|
98
|
+
async getProject(projectId) {
|
|
99
|
+
const resp = await this.request('GET', `/v1/projects/${projectId}`);
|
|
100
|
+
return resp.data;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Delete a project.
|
|
104
|
+
*
|
|
105
|
+
* @param projectId - The project UUID.
|
|
106
|
+
*/
|
|
107
|
+
async deleteProject(projectId) {
|
|
108
|
+
const headers = {
|
|
109
|
+
'Authorization': `Bearer ${this.apiKey}`,
|
|
110
|
+
};
|
|
111
|
+
const response = await fetch(`${this.baseUrl}/v1/projects/${projectId}`, { method: 'DELETE', headers });
|
|
112
|
+
if (!response.ok) {
|
|
113
|
+
let errorBody;
|
|
114
|
+
try {
|
|
115
|
+
errorBody = (await response.json());
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
// body may not be JSON
|
|
119
|
+
}
|
|
120
|
+
throw new SotaAPIError(response.status, errorBody?.error?.code ?? 'unknown', errorBody?.error?.message ?? response.statusText);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// -------------------------------------------------------------------------
|
|
124
|
+
// Deployments
|
|
125
|
+
// -------------------------------------------------------------------------
|
|
126
|
+
/**
|
|
127
|
+
* Deploy a project from a tar.gz archive.
|
|
128
|
+
*
|
|
129
|
+
* @param projectId - The project UUID.
|
|
130
|
+
* @param archive - The tar.gz archive as a `Buffer` or `Uint8Array`.
|
|
131
|
+
* @returns The created deployment.
|
|
132
|
+
*/
|
|
133
|
+
async deploy(projectId, archive) {
|
|
134
|
+
const boundary = '----SotaSDKBoundary' + Date.now();
|
|
135
|
+
const headers = {
|
|
136
|
+
'Authorization': `Bearer ${this.apiKey}`,
|
|
137
|
+
'Content-Type': `multipart/form-data; boundary=${boundary}`,
|
|
138
|
+
};
|
|
139
|
+
// Build multipart body manually (no external dependency needed)
|
|
140
|
+
const preamble = [
|
|
141
|
+
`--${boundary}\r\n`,
|
|
142
|
+
`Content-Disposition: form-data; name="archive"; filename="archive.tar.gz"\r\n`,
|
|
143
|
+
`Content-Type: application/gzip\r\n`,
|
|
144
|
+
`\r\n`,
|
|
145
|
+
].join('');
|
|
146
|
+
const epilogue = `\r\n--${boundary}--\r\n`;
|
|
147
|
+
const encoder = new TextEncoder();
|
|
148
|
+
const prefixBytes = encoder.encode(preamble);
|
|
149
|
+
const suffixBytes = encoder.encode(epilogue);
|
|
150
|
+
const archiveBytes = archive instanceof Uint8Array ? archive : new Uint8Array(archive);
|
|
151
|
+
// Concatenate into a single Uint8Array
|
|
152
|
+
const body = new Uint8Array(prefixBytes.length + archiveBytes.length + suffixBytes.length);
|
|
153
|
+
body.set(prefixBytes, 0);
|
|
154
|
+
body.set(archiveBytes, prefixBytes.length);
|
|
155
|
+
body.set(suffixBytes, prefixBytes.length + archiveBytes.length);
|
|
156
|
+
const response = await fetch(`${this.baseUrl}/v1/projects/${projectId}/deploy`, { method: 'POST', headers, body });
|
|
157
|
+
if (!response.ok) {
|
|
158
|
+
let errorBody;
|
|
159
|
+
try {
|
|
160
|
+
errorBody = (await response.json());
|
|
161
|
+
}
|
|
162
|
+
catch {
|
|
163
|
+
// body may not be JSON
|
|
164
|
+
}
|
|
165
|
+
throw new SotaAPIError(response.status, errorBody?.error?.code ?? 'unknown', errorBody?.error?.message ?? response.statusText);
|
|
166
|
+
}
|
|
167
|
+
const resp = (await response.json());
|
|
168
|
+
return resp.data;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* List all deployments for a project.
|
|
172
|
+
*
|
|
173
|
+
* @param projectId - The project UUID.
|
|
174
|
+
* @returns An array of deployments, most recent first.
|
|
175
|
+
*/
|
|
176
|
+
async listDeployments(projectId) {
|
|
177
|
+
const resp = await this.request('GET', `/v1/projects/${projectId}/deployments`);
|
|
178
|
+
return resp.data;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Get build/runtime logs for a specific deployment.
|
|
182
|
+
*
|
|
183
|
+
* @param projectId - The project UUID.
|
|
184
|
+
* @param deploymentId - The deployment UUID.
|
|
185
|
+
* @returns The raw log text.
|
|
186
|
+
*/
|
|
187
|
+
async getLogs(projectId, deploymentId) {
|
|
188
|
+
const headers = {
|
|
189
|
+
'Authorization': `Bearer ${this.apiKey}`,
|
|
190
|
+
};
|
|
191
|
+
const response = await fetch(`${this.baseUrl}/v1/projects/${projectId}/deployments/${deploymentId}/logs`, { headers });
|
|
192
|
+
if (!response.ok) {
|
|
193
|
+
let errorBody;
|
|
194
|
+
try {
|
|
195
|
+
errorBody = (await response.json());
|
|
196
|
+
}
|
|
197
|
+
catch {
|
|
198
|
+
// body may not be JSON
|
|
199
|
+
}
|
|
200
|
+
throw new SotaAPIError(response.status, errorBody?.error?.code ?? 'unknown', errorBody?.error?.message ?? response.statusText);
|
|
201
|
+
}
|
|
202
|
+
return response.text();
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Rollback to the previous deployment.
|
|
206
|
+
*
|
|
207
|
+
* @param projectId - The project UUID.
|
|
208
|
+
* @returns The restored deployment.
|
|
209
|
+
*/
|
|
210
|
+
async rollback(projectId) {
|
|
211
|
+
const resp = await this.request('POST', `/v1/projects/${projectId}/rollback`);
|
|
212
|
+
return resp.data;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Redeploy the latest deployment.
|
|
216
|
+
*
|
|
217
|
+
* @param projectId - The project UUID.
|
|
218
|
+
* @returns The new deployment.
|
|
219
|
+
*/
|
|
220
|
+
async redeploy(projectId) {
|
|
221
|
+
const resp = await this.request('POST', `/v1/projects/${projectId}/redeploy`);
|
|
222
|
+
return resp.data;
|
|
223
|
+
}
|
|
224
|
+
// -------------------------------------------------------------------------
|
|
225
|
+
// Environment Variables
|
|
226
|
+
// -------------------------------------------------------------------------
|
|
227
|
+
/**
|
|
228
|
+
* List all environment variables for a project.
|
|
229
|
+
*
|
|
230
|
+
* @param projectId - The project UUID.
|
|
231
|
+
* @returns An array of environment variables.
|
|
232
|
+
*/
|
|
233
|
+
async listEnvVars(projectId) {
|
|
234
|
+
const resp = await this.request('GET', `/v1/projects/${projectId}/envs`);
|
|
235
|
+
return resp.data;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Set an environment variable on a project.
|
|
239
|
+
*
|
|
240
|
+
* Creates the variable if it doesn't exist, or updates it if it does.
|
|
241
|
+
*
|
|
242
|
+
* @param projectId - The project UUID.
|
|
243
|
+
* @param options - The key/value pair to set.
|
|
244
|
+
*/
|
|
245
|
+
async setEnvVar(projectId, options) {
|
|
246
|
+
await this.request('POST', `/v1/projects/${projectId}/envs`, options);
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Delete an environment variable from a project.
|
|
250
|
+
*
|
|
251
|
+
* @param projectId - The project UUID.
|
|
252
|
+
* @param key - The variable name to delete.
|
|
253
|
+
*/
|
|
254
|
+
async deleteEnvVar(projectId, key) {
|
|
255
|
+
const headers = {
|
|
256
|
+
'Authorization': `Bearer ${this.apiKey}`,
|
|
257
|
+
};
|
|
258
|
+
const response = await fetch(`${this.baseUrl}/v1/projects/${projectId}/envs/${key}`, { method: 'DELETE', headers });
|
|
259
|
+
if (!response.ok) {
|
|
260
|
+
let errorBody;
|
|
261
|
+
try {
|
|
262
|
+
errorBody = (await response.json());
|
|
263
|
+
}
|
|
264
|
+
catch {
|
|
265
|
+
// body may not be JSON
|
|
266
|
+
}
|
|
267
|
+
throw new SotaAPIError(response.status, errorBody?.error?.code ?? 'unknown', errorBody?.error?.message ?? response.statusText);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error classes for the sota.io SDK.
|
|
3
|
+
*/
|
|
4
|
+
/** Base error class for all SDK errors. */
|
|
5
|
+
export declare class SotaError extends Error {
|
|
6
|
+
constructor(message: string);
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Thrown when the API returns a non-2xx response.
|
|
10
|
+
*
|
|
11
|
+
* Includes the HTTP status code and the machine-readable error code from the
|
|
12
|
+
* API response body.
|
|
13
|
+
*/
|
|
14
|
+
export declare class SotaAPIError extends SotaError {
|
|
15
|
+
/** HTTP status code (e.g. 400, 404, 500). */
|
|
16
|
+
readonly statusCode: number;
|
|
17
|
+
/** Machine-readable error code from the API (e.g. `"not_found"`). */
|
|
18
|
+
readonly code: string;
|
|
19
|
+
constructor(statusCode: number, code: string, message: string);
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,2CAA2C;AAC3C,qBAAa,SAAU,SAAQ,KAAK;gBACtB,OAAO,EAAE,MAAM;CAI5B;AAED;;;;;GAKG;AACH,qBAAa,YAAa,SAAQ,SAAS;IACzC,6CAA6C;IAC7C,SAAgB,UAAU,EAAE,MAAM,CAAC;IACnC,qEAAqE;IACrE,SAAgB,IAAI,EAAE,MAAM,CAAC;gBAEjB,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAM9D"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error classes for the sota.io SDK.
|
|
3
|
+
*/
|
|
4
|
+
/** Base error class for all SDK errors. */
|
|
5
|
+
export class SotaError extends Error {
|
|
6
|
+
constructor(message) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.name = 'SotaError';
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Thrown when the API returns a non-2xx response.
|
|
13
|
+
*
|
|
14
|
+
* Includes the HTTP status code and the machine-readable error code from the
|
|
15
|
+
* API response body.
|
|
16
|
+
*/
|
|
17
|
+
export class SotaAPIError extends SotaError {
|
|
18
|
+
/** HTTP status code (e.g. 400, 404, 500). */
|
|
19
|
+
statusCode;
|
|
20
|
+
/** Machine-readable error code from the API (e.g. `"not_found"`). */
|
|
21
|
+
code;
|
|
22
|
+
constructor(statusCode, code, message) {
|
|
23
|
+
super(message);
|
|
24
|
+
this.name = 'SotaAPIError';
|
|
25
|
+
this.statusCode = statusCode;
|
|
26
|
+
this.code = code;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,2CAA2C;AAC3C,MAAM,OAAO,SAAU,SAAQ,KAAK;IAClC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;IAC1B,CAAC;CACF;AAED;;;;;GAKG;AACH,MAAM,OAAO,YAAa,SAAQ,SAAS;IACzC,6CAA6C;IAC7B,UAAU,CAAS;IACnC,qEAAqE;IACrD,IAAI,CAAS;IAE7B,YAAY,UAAkB,EAAE,IAAY,EAAE,OAAe;QAC3D,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;QAC3B,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @sota-io/sdk — TypeScript SDK for the sota.io deployment platform.
|
|
3
|
+
*
|
|
4
|
+
* @packageDocumentation
|
|
5
|
+
*/
|
|
6
|
+
export { SotaClient } from './client.js';
|
|
7
|
+
export { SotaError, SotaAPIError } from './errors.js';
|
|
8
|
+
export type { SotaClientOptions, Project, Deployment, EnvVar, DataResponse, ListResponse, Pagination, APIErrorBody, CreateProjectOptions, SetEnvVarOptions, ListOptions, } from './types.js';
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACtD,YAAY,EACV,iBAAiB,EACjB,OAAO,EACP,UAAU,EACV,MAAM,EACN,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,oBAAoB,EACpB,gBAAgB,EAChB,WAAW,GACZ,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript type definitions for the sota.io API.
|
|
3
|
+
*/
|
|
4
|
+
/** Options for constructing a {@link SotaClient}. */
|
|
5
|
+
export interface SotaClientOptions {
|
|
6
|
+
/** sota.io API key (starts with `sota_`). */
|
|
7
|
+
apiKey: string;
|
|
8
|
+
/** API base URL. Defaults to `https://api.sota.io`. */
|
|
9
|
+
baseUrl?: string;
|
|
10
|
+
}
|
|
11
|
+
/** A sota.io project. */
|
|
12
|
+
export interface Project {
|
|
13
|
+
id: string;
|
|
14
|
+
user_id: string;
|
|
15
|
+
name: string;
|
|
16
|
+
slug: string;
|
|
17
|
+
created_at: string;
|
|
18
|
+
updated_at: string;
|
|
19
|
+
}
|
|
20
|
+
/** A single deployment of a project. */
|
|
21
|
+
export interface Deployment {
|
|
22
|
+
id: string;
|
|
23
|
+
project_id: string;
|
|
24
|
+
status: string;
|
|
25
|
+
url?: string;
|
|
26
|
+
image_tag?: string;
|
|
27
|
+
build_method?: string;
|
|
28
|
+
framework?: string;
|
|
29
|
+
error?: string;
|
|
30
|
+
created_at: string;
|
|
31
|
+
updated_at: string;
|
|
32
|
+
}
|
|
33
|
+
/** An environment variable attached to a project. */
|
|
34
|
+
export interface EnvVar {
|
|
35
|
+
id: string;
|
|
36
|
+
project_id: string;
|
|
37
|
+
key: string;
|
|
38
|
+
value?: string;
|
|
39
|
+
created_at: string;
|
|
40
|
+
updated_at: string;
|
|
41
|
+
}
|
|
42
|
+
/** Envelope for single-item API responses. */
|
|
43
|
+
export interface DataResponse<T> {
|
|
44
|
+
data: T;
|
|
45
|
+
}
|
|
46
|
+
/** Pagination metadata returned with list responses. */
|
|
47
|
+
export interface Pagination {
|
|
48
|
+
next_cursor?: string;
|
|
49
|
+
has_more: boolean;
|
|
50
|
+
}
|
|
51
|
+
/** Envelope for list API responses. */
|
|
52
|
+
export interface ListResponse<T> {
|
|
53
|
+
data: T[];
|
|
54
|
+
pagination?: Pagination;
|
|
55
|
+
}
|
|
56
|
+
/** Body returned by the API when an error occurs. */
|
|
57
|
+
export interface APIErrorBody {
|
|
58
|
+
error: {
|
|
59
|
+
code: string;
|
|
60
|
+
message: string;
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/** Options for creating a new project. */
|
|
64
|
+
export interface CreateProjectOptions {
|
|
65
|
+
/** Human-readable project name. */
|
|
66
|
+
name: string;
|
|
67
|
+
/** URL-safe slug (auto-generated from name if omitted). */
|
|
68
|
+
slug?: string;
|
|
69
|
+
}
|
|
70
|
+
/** Options for setting an environment variable. */
|
|
71
|
+
export interface SetEnvVarOptions {
|
|
72
|
+
/** Variable name. */
|
|
73
|
+
key: string;
|
|
74
|
+
/** Variable value. */
|
|
75
|
+
value: string;
|
|
76
|
+
}
|
|
77
|
+
/** Options for list endpoints that support cursor-based pagination. */
|
|
78
|
+
export interface ListOptions {
|
|
79
|
+
/** Cursor returned by a previous list call. */
|
|
80
|
+
cursor?: string;
|
|
81
|
+
/** Maximum number of items to return. */
|
|
82
|
+
limit?: number;
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,qDAAqD;AACrD,MAAM,WAAW,iBAAiB;IAChC,6CAA6C;IAC7C,MAAM,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAMD,yBAAyB;AACzB,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wCAAwC;AACxC,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,qDAAqD;AACrD,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAMD,8CAA8C;AAC9C,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,IAAI,EAAE,CAAC,CAAC;CACT;AAED,wDAAwD;AACxD,MAAM,WAAW,UAAU;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,uCAAuC;AACvC,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB;AAED,qDAAqD;AACrD,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE;QACL,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AAMD,0CAA0C;AAC1C,MAAM,WAAW,oBAAoB;IACnC,mCAAmC;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,mDAAmD;AACnD,MAAM,WAAW,gBAAgB;IAC/B,qBAAqB;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,sBAAsB;IACtB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,uEAAuE;AACvE,MAAM,WAAW,WAAW;IAC1B,+CAA+C;IAC/C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yCAAyC;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sota-io/sdk",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "TypeScript SDK for the sota.io deployment platform API",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist"
|
|
10
|
+
],
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "tsc",
|
|
13
|
+
"prepublishOnly": "npm run build"
|
|
14
|
+
},
|
|
15
|
+
"publishConfig": {
|
|
16
|
+
"access": "public"
|
|
17
|
+
},
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "https://github.com/sota-deploy/sdk"
|
|
21
|
+
},
|
|
22
|
+
"homepage": "https://sota.io/docs/api",
|
|
23
|
+
"keywords": [
|
|
24
|
+
"sota",
|
|
25
|
+
"sdk",
|
|
26
|
+
"deploy",
|
|
27
|
+
"paas",
|
|
28
|
+
"typescript",
|
|
29
|
+
"api-client"
|
|
30
|
+
],
|
|
31
|
+
"engines": {
|
|
32
|
+
"node": ">=18.0.0"
|
|
33
|
+
},
|
|
34
|
+
"license": "MIT",
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"typescript": "^5.7.0",
|
|
37
|
+
"@types/node": "^22.0.0"
|
|
38
|
+
}
|
|
39
|
+
}
|