@dockstat/docker 0.1.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 +289 -0
- package/package.json +39 -0
- package/src/docker.ts +35 -0
- package/src/environment.d.ts +15 -0
- package/src/index.ts +9 -0
- package/src/modules/_socket/index.ts +106 -0
- package/src/modules/base/index.ts +30 -0
- package/src/modules/base/types.ts +17 -0
- package/src/modules/container/index.ts +384 -0
- package/src/modules/container/types.ts +673 -0
- package/src/modules/distribution/index.ts +14 -0
- package/src/modules/distribution/types.ts +24 -0
- package/src/modules/exec/index.ts +60 -0
- package/src/modules/exec/types.ts +64 -0
- package/src/modules/images/index.ts +220 -0
- package/src/modules/images/types.ts +686 -0
- package/src/modules/networks/index.ts +87 -0
- package/src/modules/networks/types.ts +258 -0
- package/src/modules/nodes/index.ts +48 -0
- package/src/modules/nodes/types.ts +69 -0
- package/src/modules/plugins/index.ts +128 -0
- package/src/modules/plugins/types.ts +114 -0
- package/src/modules/secrets/index.ts +5 -0
- package/src/modules/secrets/types.ts +0 -0
- package/src/modules/volumes/index.ts +65 -0
- package/src/modules/volumes/types.ts +197 -0
- package/src/utils/env.ts +48 -0
- package/src/utils/error.ts +23 -0
- package/src/utils/request-options.ts +68 -0
- package/src/utils/response.ts +31 -0
- package/src/utils/url.ts +48 -0
- package/tsconfig.json +33 -0
package/README.md
ADDED
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
# @dockstat/docker
|
|
2
|
+
|
|
3
|
+
> A Bun-native, type-safe wrapper for the Docker API
|
|
4
|
+
|
|
5
|
+
**@dockstat/docker** provides a modern, fully-typed interface to Docker's remote API, built specifically for [Bun](https://bun.sh). It offers a modular architecture, comprehensive type safety, and support for both Unix sockets and TCP connections with TLS.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **Bun-Native**: Optimized for Bun's performance and APIs
|
|
10
|
+
- **Type-Safe**: Full TypeScript coverage with generated types from Docker's OpenAPI spec
|
|
11
|
+
- **Modular Architecture**: Separate modules for containers, images, networks, volumes, and more
|
|
12
|
+
- **Flexible Connection**: Support for Unix sockets, TCP, and TLS-secured connections
|
|
13
|
+
- **Environment-Based Config**: Automatically reads Docker environment variables (like the Docker CLI)
|
|
14
|
+
- **Zero Dependencies**: Minimal footprint, leveraging Bun's built-in capabilities
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
bun add @dockstat/docker
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Quick Start
|
|
23
|
+
|
|
24
|
+
### Using Environment Variables
|
|
25
|
+
|
|
26
|
+
The easiest way to get started is by letting the package auto-configure from your environment:
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
import { createDockerFromEnv } from "@dockstat/docker"
|
|
30
|
+
|
|
31
|
+
const docker = createDockerFromEnv()
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
This reads from standard Docker environment variables:
|
|
35
|
+
- `DOCKER_SOCKET` - Path to Unix socket or TCP URL (default: `/var/run/docker.sock`)
|
|
36
|
+
- `CERT_FILE`, `KEY_FILE`, `CA_FILE` - Paths to TLS certificates
|
|
37
|
+
|
|
38
|
+
### Manual Configuration
|
|
39
|
+
|
|
40
|
+
For full control over the connection:
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
import { Docker } from "@dockstat/docker"
|
|
44
|
+
|
|
45
|
+
// Unix socket connection
|
|
46
|
+
const docker = new Docker({
|
|
47
|
+
mode: "unix",
|
|
48
|
+
socketPath: "/var/run/docker.sock"
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
// TCP connection
|
|
52
|
+
const docker = new Docker({
|
|
53
|
+
mode: "tcp",
|
|
54
|
+
baseUrl: "http://localhost:2375"
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
// TCP with TLS
|
|
58
|
+
const docker = new Docker({
|
|
59
|
+
mode: "tcp",
|
|
60
|
+
baseUrl: "https://remote-docker:2376",
|
|
61
|
+
tls: {
|
|
62
|
+
cert: Bun.file("/path/to/cert.pem"),
|
|
63
|
+
key: Bun.file("/path/to/key.pem"),
|
|
64
|
+
ca: Bun.file("/path/to/ca.pem")
|
|
65
|
+
}
|
|
66
|
+
})
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Verify Connection
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
const isConnected = await docker.ping()
|
|
73
|
+
console.log("Docker daemon reachable:", isConnected)
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Usage
|
|
77
|
+
|
|
78
|
+
### Containers
|
|
79
|
+
|
|
80
|
+
List all containers:
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
const containers = await docker.containers.list()
|
|
84
|
+
console.log(containers)
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
List running containers only:
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
const runningContainers = await docker.containers.list({
|
|
91
|
+
all: false
|
|
92
|
+
})
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Create and start a container:
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
const result = await docker.containers.create({
|
|
99
|
+
Image: "nginx:latest",
|
|
100
|
+
Env: ["NGINX_PORT=80"]
|
|
101
|
+
})
|
|
102
|
+
await docker.containers.start(result.Id)
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Inspect a container:
|
|
106
|
+
|
|
107
|
+
```ts
|
|
108
|
+
const details = await docker.containers.inspect("my-container")
|
|
109
|
+
console.log(details.State)
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Get container logs:
|
|
113
|
+
|
|
114
|
+
```ts
|
|
115
|
+
const logs = await docker.containers.logs("my-container", {
|
|
116
|
+
stdout: true,
|
|
117
|
+
stderr: true
|
|
118
|
+
})
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Stop and remove a container:
|
|
122
|
+
|
|
123
|
+
```ts
|
|
124
|
+
await docker.containers.stop("my-container")
|
|
125
|
+
await docker.containers.remove("my-container", false, true)
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Images
|
|
129
|
+
|
|
130
|
+
List images:
|
|
131
|
+
|
|
132
|
+
```ts
|
|
133
|
+
const images = await docker.images.list()
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Pull an image:
|
|
137
|
+
|
|
138
|
+
```ts
|
|
139
|
+
await docker.images.create("nginx:latest", {})
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Networks
|
|
143
|
+
|
|
144
|
+
List networks:
|
|
145
|
+
|
|
146
|
+
```ts
|
|
147
|
+
const networks = await docker.networks.list()
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Create a network:
|
|
151
|
+
|
|
152
|
+
```ts
|
|
153
|
+
await docker.networks.create({
|
|
154
|
+
Name: "my-network",
|
|
155
|
+
Driver: "bridge"
|
|
156
|
+
})
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Volumes
|
|
160
|
+
|
|
161
|
+
List volumes:
|
|
162
|
+
|
|
163
|
+
```ts
|
|
164
|
+
const volumes = await docker.volumes.list()
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Create a volume:
|
|
168
|
+
|
|
169
|
+
```ts
|
|
170
|
+
await docker.volumes.create({
|
|
171
|
+
Name: "my-volume",
|
|
172
|
+
Driver: "local"
|
|
173
|
+
})
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Executing Commands
|
|
177
|
+
|
|
178
|
+
Run a command in a container:
|
|
179
|
+
|
|
180
|
+
```ts
|
|
181
|
+
// Create exec instance
|
|
182
|
+
const exec = await docker.containers.execCreate("my-container", {
|
|
183
|
+
AttachStdout: true,
|
|
184
|
+
AttachStderr: true,
|
|
185
|
+
Cmd: ["ls", "-la", "/app"]
|
|
186
|
+
})
|
|
187
|
+
|
|
188
|
+
// Start exec and get output
|
|
189
|
+
const response = await docker.containers.execStart(exec.Id)
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### Statistics
|
|
193
|
+
|
|
194
|
+
Get container resource usage:
|
|
195
|
+
|
|
196
|
+
```ts
|
|
197
|
+
// Get single stats snapshot
|
|
198
|
+
const stats = await docker.containers.stats("my-container")
|
|
199
|
+
console.log(stats.cpu_stats, stats.memory_stats)
|
|
200
|
+
|
|
201
|
+
// Stream stats
|
|
202
|
+
const stream = await docker.containers.stats("my-container", { stream: true })
|
|
203
|
+
// stream is a Response object with streaming body
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## API Modules
|
|
207
|
+
|
|
208
|
+
The `Docker` class provides access to the following modules:
|
|
209
|
+
|
|
210
|
+
- **`containers`** - Container lifecycle, logs, stats, exec, filesystem operations
|
|
211
|
+
- **`images`** - Image management, building, pulling
|
|
212
|
+
- **`networks`** - Network creation, inspection, connection management
|
|
213
|
+
- **`volumes`** - Volume lifecycle and management
|
|
214
|
+
- **`exec`** - Execute commands in running containers
|
|
215
|
+
- **`distribution`** - Registry and distribution operations
|
|
216
|
+
- **`nodes`** - Swarm node management
|
|
217
|
+
|
|
218
|
+
All modules are fully typed with TypeScript types generated from Docker's OpenAPI specification.
|
|
219
|
+
|
|
220
|
+
## Configuration
|
|
221
|
+
|
|
222
|
+
### Connection Modes
|
|
223
|
+
|
|
224
|
+
**Unix Socket** (default):
|
|
225
|
+
|
|
226
|
+
```ts
|
|
227
|
+
{
|
|
228
|
+
mode: "unix",
|
|
229
|
+
socketPath: "/var/run/docker.sock",
|
|
230
|
+
tls?: TLSOptions
|
|
231
|
+
}
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
**TCP**:
|
|
235
|
+
|
|
236
|
+
```ts
|
|
237
|
+
{
|
|
238
|
+
mode: "tcp",
|
|
239
|
+
baseUrl: "http://localhost:2375",
|
|
240
|
+
tls?: TLSOptions
|
|
241
|
+
}
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### Environment Variables
|
|
245
|
+
|
|
246
|
+
When using `createDockerFromEnv()`, the following environment variables are respected:
|
|
247
|
+
|
|
248
|
+
| Variable | Description | Default |
|
|
249
|
+
|----------|-------------|---------|
|
|
250
|
+
| `DOCKER_SOCKET` | Unix socket path or TCP URL | `/var/run/docker.sock` |
|
|
251
|
+
| `CERT_FILE` | Path to client certificate | - |
|
|
252
|
+
| `KEY_FILE` | Path to client key | - |
|
|
253
|
+
| `CA_FILE` | Path to CA certificate | - |
|
|
254
|
+
|
|
255
|
+
## TypeScript Support
|
|
256
|
+
|
|
257
|
+
This package includes comprehensive TypeScript types for all Docker API operations.
|
|
258
|
+
|
|
259
|
+
All methods return properly typed responses:
|
|
260
|
+
|
|
261
|
+
```ts
|
|
262
|
+
import type { ContainerInspectResponse } from "@dockstat/docker"
|
|
263
|
+
|
|
264
|
+
const container: ContainerInspectResponse = await docker.containers.inspect("my-id")
|
|
265
|
+
// Full type safety and autocomplete
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
## Part of the DockStat Ecosystem
|
|
269
|
+
|
|
270
|
+
`@dockstat/docker` is a core package in the [DockStat](https://github.com/its4nik/dockstat) project, an extensible container administration and monitoring platform. It powers Docker interactions throughout the DockStat ecosystem, providing a unified, type-safe interface for container management.
|
|
271
|
+
|
|
272
|
+
## Contributing
|
|
273
|
+
|
|
274
|
+
Contributions are welcome! Please follow these guidelines:
|
|
275
|
+
|
|
276
|
+
1. Follow the existing code style and structure
|
|
277
|
+
2. Ensure TypeScript types are properly defined
|
|
278
|
+
3. Add JSDoc comments for public APIs
|
|
279
|
+
4. Test your changes thoroughly
|
|
280
|
+
|
|
281
|
+
For detailed development guidelines, see the [main DockStat README](https://github.com/its4nik/dockstat).
|
|
282
|
+
|
|
283
|
+
## License
|
|
284
|
+
|
|
285
|
+
[ Mozilla Public License Version 2.0 ](https://www.mozilla.org/en-US/MPL/2.0/)
|
|
286
|
+
|
|
287
|
+
---
|
|
288
|
+
|
|
289
|
+
**Made with ❤️ for the DockStat project**
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@dockstat/docker",
|
|
3
|
+
"description": "A bun native, typesafe wrapper for the docker API",
|
|
4
|
+
"author": {
|
|
5
|
+
"email": "info@itsnik.de",
|
|
6
|
+
"name": "ItsNik",
|
|
7
|
+
"url": "https://itsnik.de"
|
|
8
|
+
},
|
|
9
|
+
"keywords": [
|
|
10
|
+
"docker",
|
|
11
|
+
"bun"
|
|
12
|
+
],
|
|
13
|
+
"version": "0.1.0",
|
|
14
|
+
"license": "MPL-2.0",
|
|
15
|
+
"repository": {
|
|
16
|
+
"directory": "packages/bun-docker",
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "https://github.com/its4nik/dockstat"
|
|
19
|
+
},
|
|
20
|
+
"module": "src/index.ts",
|
|
21
|
+
"type": "module",
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"@types/bun": "latest",
|
|
24
|
+
"@types/node": "^25.5.0"
|
|
25
|
+
},
|
|
26
|
+
"peerDependencies": {
|
|
27
|
+
"typescript": "^5"
|
|
28
|
+
},
|
|
29
|
+
"files": [
|
|
30
|
+
"src",
|
|
31
|
+
"README.md",
|
|
32
|
+
"tsconfig.json"
|
|
33
|
+
],
|
|
34
|
+
"scripts": {
|
|
35
|
+
"build": "bun build --target=bun --production --sourcemap=external --outdir=dist src/index.ts",
|
|
36
|
+
"typegen": "bunx tsc --declaration --pretty --outFile dist/types.d.ts --emitDeclarationOnly src/index.ts",
|
|
37
|
+
"publish": "bun run build && bun run typegen && bun pm pack --destination ./dist && npm publish --access public ./dist/*.tgz ; rm -r ./dist"
|
|
38
|
+
}
|
|
39
|
+
}
|
package/src/docker.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { BaseModule } from "./modules/base"
|
|
2
|
+
import type { ConnectionConfig } from "./modules/base/types"
|
|
3
|
+
import { ContainerModule } from "./modules/container"
|
|
4
|
+
import { DistributionModule } from "./modules/distribution"
|
|
5
|
+
import { ExecModule } from "./modules/exec"
|
|
6
|
+
import { ImagesModule } from "./modules/images"
|
|
7
|
+
import { NetworksModule } from "./modules/networks"
|
|
8
|
+
import { NodesModule } from "./modules/nodes"
|
|
9
|
+
import { VolumeModule } from "./modules/volumes"
|
|
10
|
+
|
|
11
|
+
export class Docker {
|
|
12
|
+
public readonly containers: ContainerModule
|
|
13
|
+
public readonly images: ImagesModule
|
|
14
|
+
public readonly networks: NetworksModule
|
|
15
|
+
public readonly volumes: VolumeModule
|
|
16
|
+
public readonly exec: ExecModule
|
|
17
|
+
public readonly distribution: DistributionModule
|
|
18
|
+
public readonly nodes: NodesModule
|
|
19
|
+
|
|
20
|
+
constructor(private config: ConnectionConfig) {
|
|
21
|
+
this.containers = new ContainerModule(config)
|
|
22
|
+
this.images = new ImagesModule(config)
|
|
23
|
+
this.networks = new NetworksModule(config)
|
|
24
|
+
this.volumes = new VolumeModule(config)
|
|
25
|
+
this.exec = new ExecModule(config)
|
|
26
|
+
this.distribution = new DistributionModule(config)
|
|
27
|
+
this.nodes = new NodesModule(config)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async ping(): Promise<boolean> {
|
|
31
|
+
const requester = new BaseModule(this.config)
|
|
32
|
+
const res = await requester.request("/_ping", "GET")
|
|
33
|
+
return res.ok
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
declare global {
|
|
2
|
+
namespace NodeJS {
|
|
3
|
+
interface ProcessEnv {
|
|
4
|
+
DOCKER_SOCKET: "/var/run/docker.sock" | string
|
|
5
|
+
ENABLE_API?: string
|
|
6
|
+
API_KEYS?: string
|
|
7
|
+
API_PORT?: string
|
|
8
|
+
KEY_FILE?: "./key.pem"
|
|
9
|
+
CERT_FILE?: "./cert.pem"
|
|
10
|
+
CA_FILE?: "./ca.pem"
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export {}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import type { ReadableStreamDefaultReader } from "node:stream/web"
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* WebSocket-like interface for Docker container attach
|
|
5
|
+
* Uses the attach endpoint with stream wrapping for compatibility with Unix sockets
|
|
6
|
+
*
|
|
7
|
+
* @note Currently supports read-only operations (receiving stdout/stderr). Full WebSocket
|
|
8
|
+
* protocol support with bidirectional communication is planned for future versions.
|
|
9
|
+
*/
|
|
10
|
+
export class DockerWebSocket {
|
|
11
|
+
private static readonly CONNECTING = 0
|
|
12
|
+
private static readonly OPEN = 1
|
|
13
|
+
private static readonly CLOSING = 2
|
|
14
|
+
private static readonly CLOSED = 3
|
|
15
|
+
|
|
16
|
+
private readyStateValue: number = DockerWebSocket.CONNECTING
|
|
17
|
+
private listeners: Map<string, Array<(event: unknown) => void>> = new Map()
|
|
18
|
+
private reader: ReadableStreamDefaultReader | null = null
|
|
19
|
+
|
|
20
|
+
addEventListener(type: string, listener: (event: unknown) => void) {
|
|
21
|
+
if (!this.listeners.has(type)) {
|
|
22
|
+
this.listeners.set(type, [])
|
|
23
|
+
}
|
|
24
|
+
this.listeners.get(type)?.push(listener)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
removeEventListener(type: string, listener: (event: unknown) => void) {
|
|
28
|
+
const typeListeners = this.listeners.get(type)
|
|
29
|
+
if (typeListeners) {
|
|
30
|
+
const index = typeListeners.indexOf(listener)
|
|
31
|
+
if (index > -1) {
|
|
32
|
+
typeListeners.splice(index, 1)
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async attach(response: Response) {
|
|
38
|
+
if (!response.body) {
|
|
39
|
+
this.emit("error", new Error("Response has no body"))
|
|
40
|
+
this.readyStateValue = DockerWebSocket.CLOSED
|
|
41
|
+
this.emit("close", {})
|
|
42
|
+
return
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
this.reader = response.body.getReader()
|
|
46
|
+
this.readyStateValue = DockerWebSocket.OPEN
|
|
47
|
+
this.emit("open", {})
|
|
48
|
+
|
|
49
|
+
try {
|
|
50
|
+
while (this.readyStateValue === DockerWebSocket.OPEN) {
|
|
51
|
+
const { done, value } = await this.reader.read()
|
|
52
|
+
if (done) break
|
|
53
|
+
|
|
54
|
+
// Decode the chunk to string
|
|
55
|
+
const text = new TextDecoder().decode(value)
|
|
56
|
+
this.emit("message", { data: text })
|
|
57
|
+
}
|
|
58
|
+
} catch (error) {
|
|
59
|
+
if (this.readyStateValue !== DockerWebSocket.CLOSING) {
|
|
60
|
+
this.emit("error", error)
|
|
61
|
+
}
|
|
62
|
+
} finally {
|
|
63
|
+
this.readyStateValue = DockerWebSocket.CLOSED
|
|
64
|
+
this.emit("close", {})
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
close() {
|
|
69
|
+
if (this.readyStateValue === DockerWebSocket.CLOSED) return
|
|
70
|
+
|
|
71
|
+
this.readyStateValue = DockerWebSocket.CLOSING
|
|
72
|
+
|
|
73
|
+
if (this.reader) {
|
|
74
|
+
this.reader.cancel().catch(() => {})
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
this.readyStateValue = DockerWebSocket.CLOSED
|
|
78
|
+
this.emit("close", {})
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
get CONNECTING() {
|
|
82
|
+
return DockerWebSocket.CONNECTING
|
|
83
|
+
}
|
|
84
|
+
get OPEN() {
|
|
85
|
+
return DockerWebSocket.OPEN
|
|
86
|
+
}
|
|
87
|
+
get CLOSING() {
|
|
88
|
+
return DockerWebSocket.CLOSING
|
|
89
|
+
}
|
|
90
|
+
get CLOSED() {
|
|
91
|
+
return DockerWebSocket.CLOSED
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
get readyState() {
|
|
95
|
+
return this.readyStateValue
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
private emit(type: string, event: unknown) {
|
|
99
|
+
const listeners = this.listeners.get(type)
|
|
100
|
+
if (listeners) {
|
|
101
|
+
for (const listener of listeners) {
|
|
102
|
+
listener(event)
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { BodyInit, HeadersInit } from "bun"
|
|
2
|
+
import { prepareRequestOptions } from "../../utils/request-options"
|
|
3
|
+
import { handleDockerResponse } from "../../utils/response"
|
|
4
|
+
import { buildDockerUrl, buildQueryString } from "../../utils/url"
|
|
5
|
+
import { DockerWebSocket } from "../_socket"
|
|
6
|
+
import type { ConnectionConfig, HttpMethod } from "./types"
|
|
7
|
+
|
|
8
|
+
export class BaseModule {
|
|
9
|
+
constructor(private config: ConnectionConfig) {}
|
|
10
|
+
|
|
11
|
+
protected ws = new DockerWebSocket()
|
|
12
|
+
|
|
13
|
+
async request(
|
|
14
|
+
path: string,
|
|
15
|
+
method: HttpMethod = "GET",
|
|
16
|
+
body?: BodyInit | object,
|
|
17
|
+
headers?: HeadersInit,
|
|
18
|
+
params?: object
|
|
19
|
+
) {
|
|
20
|
+
const dockerApiVersion = this.config.dockerAPIVersion || "1.54"
|
|
21
|
+
const query = buildQueryString(params)
|
|
22
|
+
const url = buildDockerUrl(this.config, path, query, dockerApiVersion)
|
|
23
|
+
|
|
24
|
+
const options = prepareRequestOptions(this.config, method, body, headers, url)
|
|
25
|
+
|
|
26
|
+
const response = await fetch(url, options)
|
|
27
|
+
|
|
28
|
+
return handleDockerResponse(response, path, dockerApiVersion, params)
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { TLSOptions } from "bun"
|
|
2
|
+
|
|
3
|
+
export type ConnectionMode = "unix" | "tcp"
|
|
4
|
+
|
|
5
|
+
export interface ConnectionConfig {
|
|
6
|
+
mode: ConnectionMode
|
|
7
|
+
// For Unix: the file path
|
|
8
|
+
socketPath?: string
|
|
9
|
+
// For TCP: the full base URL (e.g., http://192.168.1.50:2375)
|
|
10
|
+
baseUrl?: string
|
|
11
|
+
// TLS options (used for TCP or TLS-secured Unix sockets)
|
|
12
|
+
tls?: TLSOptions
|
|
13
|
+
// The docker API version
|
|
14
|
+
dockerAPIVersion?: string
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export type HttpMethod = "GET" | "POST" | "PUT" | "DELETE" | "HEAD"
|