@dockstat/docker 0.1.0 → 0.1.2

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.
@@ -1,65 +0,0 @@
1
- import { BaseModule } from "../base"
2
- import type {
3
- ListVolumesOptions,
4
- PruneVolumesOptions,
5
- Volume,
6
- VolumeCreateRequest,
7
- VolumeListResponse,
8
- VolumePruneResponse,
9
- VolumeUpdateRequest,
10
- } from "./types"
11
-
12
- /**
13
- * Volume module for Docker API
14
- */
15
- export class VolumeModule extends BaseModule {
16
- /**
17
- * List volumes
18
- */
19
- async list(options?: ListVolumesOptions): Promise<VolumeListResponse> {
20
- const res = await this.request(`/volumes`, "GET", undefined, undefined, options)
21
- return (await res.json()) as VolumeListResponse
22
- }
23
-
24
- /**
25
- * Create a volume
26
- */
27
- async create(config: VolumeCreateRequest): Promise<Volume> {
28
- const res = await this.request("/volumes/create", "POST", config)
29
- return (await res.json()) as Volume
30
- }
31
-
32
- /**
33
- * Inspect a volume
34
- */
35
- async inspect(name: string): Promise<Volume> {
36
- const res = await this.request(`/volumes/${encodeURIComponent(name)}`)
37
- return (await res.json()) as Volume
38
- }
39
-
40
- /**
41
- * Update a volume (for cluster volumes only)
42
- */
43
- async update(name: string, body: VolumeUpdateRequest, version: number): Promise<void> {
44
- await this.request(`/volumes/${encodeURIComponent(name)}`, "PUT", body, undefined, {
45
- version,
46
- })
47
- }
48
-
49
- /**
50
- * Remove a volume
51
- */
52
- async remove(name: string, force: boolean = false): Promise<void> {
53
- await this.request(`/volumes/${encodeURIComponent(name)}`, "DELETE", undefined, undefined, {
54
- force,
55
- })
56
- }
57
-
58
- /**
59
- * Prune unused volumes
60
- */
61
- async prune(options?: PruneVolumesOptions): Promise<VolumePruneResponse> {
62
- const res = await this.request(`/volumes/prune`, "POST", undefined, undefined, options)
63
- return (await res.json()) as VolumePruneResponse
64
- }
65
- }
@@ -1,197 +0,0 @@
1
- /**
2
- * Volume information
3
- */
4
- export interface Volume {
5
- Name: string
6
- Driver: string
7
- Mountpoint: string
8
- CreatedAt?: string
9
- Status?: Record<string, string>
10
- Labels: Record<string, string>
11
- Scope: "local" | "global"
12
- ClusterVolume?: ClusterVolume
13
- Options?: Record<string, string>
14
- UsageData?: VolumeUsageData
15
- }
16
-
17
- /**
18
- * Volume usage data
19
- */
20
- export interface VolumeUsageData {
21
- Size: number
22
- RefCount: number
23
- }
24
-
25
- /**
26
- * Volumes disk usage information
27
- */
28
- export interface VolumesDiskUsage {
29
- ActiveCount: number
30
- TotalCount: number
31
- Reclaimable: number
32
- TotalSize: number
33
- Items?: Volume[]
34
- }
35
-
36
- /**
37
- * Volume create request
38
- */
39
- export interface VolumeCreateRequest {
40
- Name?: string
41
- Driver?: string
42
- DriverOpts?: Record<string, string>
43
- Labels?: Record<string, string>
44
- ClusterVolumeSpec?: ClusterVolumeSpec
45
- }
46
-
47
- /**
48
- * Volume list response
49
- */
50
- export interface VolumeListResponse {
51
- Volumes: Volume[]
52
- Warnings?: string[]
53
- }
54
-
55
- /**
56
- * Volume prune response
57
- */
58
- export interface VolumePruneResponse {
59
- VolumesDeleted?: string[]
60
- SpaceReclaimed: number
61
- }
62
-
63
- /**
64
- * Cluster volume information (Swarm CSI cluster volumes)
65
- */
66
- export interface ClusterVolume {
67
- ID?: string
68
- Version?: ObjectVersion
69
- CreatedAt?: string
70
- UpdatedAt?: string
71
- Spec?: ClusterVolumeSpec
72
- Info?: ClusterVolumeInfo
73
- PublishStatus?: ClusterVolumePublishStatus[]
74
- }
75
-
76
- /**
77
- * Object version
78
- */
79
- export interface ObjectVersion {
80
- Index: number
81
- }
82
-
83
- /**
84
- * Cluster volume spec
85
- */
86
- export interface ClusterVolumeSpec {
87
- Group?: string
88
- AccessMode?: ClusterVolumeAccessMode
89
- Secrets?: ClusterVolumeSecret[]
90
- AccessibilityRequirements?: ClusterVolumeAccessibilityRequirements
91
- CapacityRange?: ClusterVolumeCapacityRange
92
- Availability?: "active" | "pause" | "drain"
93
- }
94
-
95
- /**
96
- * Cluster volume access mode
97
- */
98
- export interface ClusterVolumeAccessMode {
99
- Scope: "single" | "multi"
100
- Sharing: "none" | "readonly" | "onewriter" | "all"
101
- MountVolume?: ClusterVolumeMountVolume
102
- BlockVolume?: ClusterVolumeBlockVolume
103
- }
104
-
105
- /**
106
- * Cluster volume mount volume options
107
- */
108
- export interface ClusterVolumeMountVolume {
109
- FsType?: string
110
- MountFlags?: string[]
111
- }
112
-
113
- /**
114
- * Cluster volume block volume options
115
- */
116
- export interface ClusterVolumeBlockVolume {
117
- [key: string]: string
118
- }
119
-
120
- /**
121
- * Cluster volume secret
122
- */
123
- export interface ClusterVolumeSecret {
124
- Key: string
125
- Secret: string
126
- }
127
-
128
- /**
129
- * Cluster volume accessibility requirements
130
- */
131
- export interface ClusterVolumeAccessibilityRequirements {
132
- Requisite?: Topology[]
133
- Preferred?: Topology[]
134
- }
135
-
136
- /**
137
- * Cluster volume capacity range
138
- */
139
- export interface ClusterVolumeCapacityRange {
140
- RequiredBytes?: number
141
- LimitBytes?: number
142
- }
143
-
144
- /**
145
- * Cluster volume info
146
- */
147
- export interface ClusterVolumeInfo {
148
- CapacityBytes?: number
149
- VolumeContext?: Record<string, string>
150
- VolumeID?: string
151
- AccessibleTopology?: Topology[]
152
- }
153
-
154
- /**
155
- * Cluster volume publish status
156
- */
157
- export interface ClusterVolumePublishStatus {
158
- NodeID: string
159
- State: "pending-publish" | "published" | "pending-node-unpublish" | "pending-controller-unpublish"
160
- PublishContext?: Record<string, string>
161
- }
162
-
163
- /**
164
- * Topology information
165
- */
166
- export interface Topology {
167
- [key: string]: string
168
- }
169
-
170
- /**
171
- * List volumes options
172
- */
173
- export interface ListVolumesOptions {
174
- filters?: {
175
- dangling?: boolean[]
176
- driver?: string[]
177
- label?: string[]
178
- name?: string[]
179
- }
180
- }
181
-
182
- /**
183
- * Prune volumes options
184
- */
185
- export interface PruneVolumesOptions {
186
- filters?: {
187
- label?: string[]
188
- all?: boolean[]
189
- }
190
- }
191
-
192
- /**
193
- * Volume update request (for cluster volumes)
194
- */
195
- export interface VolumeUpdateRequest {
196
- Spec: ClusterVolumeSpec
197
- }
package/src/utils/env.ts DELETED
@@ -1,48 +0,0 @@
1
- import { env } from "node:process"
2
- import type { ConnectionConfig } from "../modules/base/types"
3
-
4
- const loadTls = () => {
5
- const hasCerts = env.CERT_FILE && env.KEY_FILE
6
- if (!hasCerts) return undefined
7
-
8
- return {
9
- ca: env.CA_FILE ? Bun.file(env.CA_FILE) : undefined,
10
- cert: env.CERT_FILE ? Bun.file(env.CERT_FILE) : undefined,
11
- key: env.KEY_FILE ? Bun.file(env.KEY_FILE) : undefined,
12
- }
13
- }
14
-
15
- export const getConnectionConfig = (): ConnectionConfig => {
16
- const rawHost = env.DOCKER_SOCKET || "/var/run/docker.sock"
17
- const tls = loadTls()
18
-
19
- if (rawHost.startsWith("unix://")) {
20
- return {
21
- mode: "unix",
22
- socketPath: rawHost.replace("unix://", ""),
23
- tls,
24
- }
25
- }
26
-
27
- if (rawHost.startsWith("tcp://") || rawHost.startsWith("http://")) {
28
- let protocol = "http://"
29
-
30
- if (tls) {
31
- protocol = "https://"
32
- }
33
-
34
- const cleanHost = rawHost.replace(/^tcp:\/\/|^http:\/\//, "")
35
-
36
- return {
37
- mode: "tcp",
38
- baseUrl: `${protocol}${cleanHost}`,
39
- tls,
40
- }
41
- }
42
-
43
- return {
44
- mode: "unix",
45
- socketPath: rawHost,
46
- tls,
47
- }
48
- }
@@ -1,23 +0,0 @@
1
- export class DockerError extends Error {
2
- status: number
3
- path: string
4
- version: string
5
- params: object | string
6
-
7
- constructor(
8
- message: string,
9
- status: number,
10
- path: string,
11
- version: string,
12
- params: object | string
13
- ) {
14
- super(message)
15
- this.name = "DockerError"
16
- this.status = status
17
- this.path = path
18
- this.version = version
19
- this.params = params
20
-
21
- Object.setPrototypeOf(this, DockerError.prototype)
22
- }
23
- }
@@ -1,68 +0,0 @@
1
- import type { BodyInit, HeadersInit } from "bun"
2
- import type { ConnectionConfig, HttpMethod } from "../modules/base/types"
3
-
4
- export function prepareRequestOptions(
5
- config: ConnectionConfig,
6
- method: HttpMethod,
7
- body?: BodyInit | object,
8
- headers?: HeadersInit,
9
- url?: string
10
- ): BunFetchRequestInit {
11
- const isJsonBody = typeof body === "object" && !(body instanceof FormData) && body !== undefined
12
-
13
- const baseHeaders: Record<string, string> = {
14
- Host: "localhost",
15
- }
16
-
17
- if (isJsonBody) {
18
- baseHeaders["Content-Type"] = "application/json"
19
- }
20
-
21
- // Merge additional headers
22
- if (headers) {
23
- if (headers instanceof Headers) {
24
- headers.forEach((value, key) => {
25
- baseHeaders[key] = value
26
- })
27
- } else if (Array.isArray(headers)) {
28
- headers.forEach(([key, value]) => {
29
- if (key !== undefined && value !== undefined) {
30
- baseHeaders[key] = value
31
- }
32
- })
33
- } else {
34
- Object.assign(baseHeaders, headers)
35
- }
36
- }
37
-
38
- const requestBody = isJsonBody
39
- ? JSON.stringify(body)
40
- : (body as unknown as any)
41
-
42
- const options: BunFetchRequestInit = {
43
- method,
44
- headers: baseHeaders,
45
- body: requestBody,
46
- }
47
-
48
- if (config.mode !== "unix" && url) {
49
- try {
50
- const urlObj = new URL(url)
51
- baseHeaders["Host"] = urlObj.host
52
- } catch (_) {
53
- // Ignore URL parsing errors, keep default Host
54
- }
55
- }
56
-
57
- // Configure Unix socket
58
- if (config.mode === "unix" && config.socketPath) {
59
- options.unix = config.socketPath
60
- }
61
-
62
- // Configure TLS
63
- if (config.tls) {
64
- options.tls = config.tls
65
- }
66
-
67
- return options
68
- }
@@ -1,31 +0,0 @@
1
- import { DockerError } from "./error"
2
-
3
- export async function handleDockerResponse(
4
- response: Response,
5
- path: string,
6
- apiVersion: string,
7
- params:object | undefined
8
- ): Promise<Response> {
9
- if (!response.ok) {
10
- let text = await response.text()
11
-
12
- try {
13
- const parsed = JSON.parse(text)
14
- if (parsed.message) {
15
- text = parsed.message
16
- }
17
- } catch (_) {
18
- // If JSON parsing fails, we stick with the raw text response
19
- }
20
-
21
- throw new DockerError(
22
- `Docker API Error (${response.status}): ${text}`,
23
- response.status,
24
- path,
25
- apiVersion,
26
- params || "No params defined"
27
- )
28
- }
29
-
30
- return response
31
- }
package/src/utils/url.ts DELETED
@@ -1,48 +0,0 @@
1
- import type { ConnectionConfig } from "../modules/base/types"
2
-
3
- /**
4
- * Converts an object of parameters into a URL query string.
5
- * Handles strings, numbers, booleans, and JSON serializable objects.
6
- */
7
- export function buildQueryString(params?: object): string | undefined {
8
- if (!params) return undefined
9
-
10
- const urlParams = new URLSearchParams()
11
-
12
- for (const [key, value] of Object.entries(params)) {
13
- if (value === undefined) continue
14
-
15
- if (typeof value === "string") {
16
- urlParams.append(key, value)
17
- } else if (typeof value === "number" || typeof value === "boolean") {
18
- urlParams.append(key, value.toString())
19
- } else {
20
- urlParams.append(key, JSON.stringify(value))
21
- }
22
- }
23
-
24
- return urlParams.toString()
25
- }
26
-
27
- /**
28
- * Constructs the full request URL based on the connection mode (Unix/Http) and API version.
29
- */
30
- export function buildDockerUrl(
31
- config: ConnectionConfig,
32
- path: string,
33
- query: string | undefined,
34
- apiVersion: string
35
- ): string {
36
- const queryString = query ? `?${query}` : ""
37
-
38
- if (config.mode === "unix") {
39
- // In Unix mode, the hostname doesn't matter
40
- return `http://localhost/${apiVersion}${path}${queryString}`
41
- }
42
-
43
- // HTTP/HTTPS mode
44
- const baseUrl = config.baseUrl || ""
45
- const separator = baseUrl.endsWith("/") ? "" : "/"
46
-
47
- return `${baseUrl}${separator}${apiVersion}${path}${queryString}`
48
- }