@hallmaster/docker.js 0.0.5 → 0.0.7

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 ADDED
@@ -0,0 +1,60 @@
1
+ # Docker.js
2
+
3
+ This repository is heavily used for the Hallmaster project, that you can check
4
+ out [right here](https://github.com/hallmasterorg/hallmaster).
5
+
6
+ It is a library used to manipulate Docker containers, images and all interfaces
7
+ that can be managed by the Docker Engine.
8
+
9
+ ## How to use
10
+
11
+ The entrypoint of this library is the `DockerSocket` object. It has to be
12
+ instantiated given a UNIX socket (the one used by the Docker Engine) as well as
13
+ the API hostname.
14
+
15
+ ```typescript
16
+ // index.ts
17
+ import { DockerSocket } from "@hallmaster/docker.js";
18
+
19
+ (async function () {
20
+ const socket = new DockerSocket();
21
+
22
+ await socket.init(); // prepare the UNIX socket to be used
23
+
24
+ // if you want, you may authenticate to a Docker Image registry
25
+ // await socket.authenticate(
26
+ // "ghcr.io",
27
+ // "github_username",
28
+ // "github_pat",
29
+ // );
30
+ // console.log(socket.token);
31
+
32
+ // you can get the information of the API from the socket such as the version
33
+ // of the Docker Engine
34
+ console.log(await socket.info());
35
+ })();
36
+ ```
37
+
38
+ Once you have instantiated the `DockerSocket` object and initialized it with the
39
+ `init()` method, you are ready to use it everywhere.
40
+
41
+ For instance, to fetch data from containers, you may use this snippet :
42
+
43
+ ```typescript
44
+ import ( DockerContainer ) from "@hallmaster/docker.js";
45
+
46
+ (async function() {
47
+ // ...
48
+
49
+ const containerApi = new DockerContainer(dockerSocket);
50
+
51
+ const containers = await containerApi.list();
52
+ for (const container of containers) {
53
+ const containerLogs = await containerApi.logs(container.Id);
54
+ console.log("-----------");
55
+ console.log(`Logs for the container #${container.Id}`);
56
+ console.log(containerLogs);
57
+ console.log("-----------");
58
+ }
59
+ })();
60
+ ```
@@ -0,0 +1,33 @@
1
+ import DockerSocket from "./DockerSocket";
2
+ import type { DockerContainerStats } from "./types/DockerContainerStats";
3
+ import type { DockerContainerSumary } from "./types/DockerContainerSummary";
4
+ import type { DockerContainerTop } from "./types/DockerContainerTop";
5
+ export default class DockerContainer {
6
+ private readonly dockerSocket;
7
+ constructor(dockerSocket: DockerSocket);
8
+ list(options?: {
9
+ all?: boolean;
10
+ limit?: number;
11
+ size?: boolean;
12
+ filters?: Record<string, string[]>;
13
+ }): Promise<DockerContainerSumary>;
14
+ get(containerId: string, size?: boolean): Promise<DockerContainer>;
15
+ top(containerId: string, psArgs?: string): Promise<DockerContainerTop>;
16
+ logs(containerId: string, options?: {
17
+ follow?: boolean;
18
+ stdout?: boolean;
19
+ stderr?: boolean;
20
+ since?: number;
21
+ until?: number;
22
+ timestamps?: boolean;
23
+ tail?: number | "all";
24
+ }): Promise<string>;
25
+ stats(containerId: string, options?: {
26
+ stream: true;
27
+ oneShot?: false;
28
+ } | {
29
+ stream: false;
30
+ oneShot?: boolean;
31
+ }): Promise<DockerContainerStats>;
32
+ }
33
+ //# sourceMappingURL=DockerContainer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DockerContainer.d.ts","sourceRoot":"","sources":["../src/DockerContainer.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACzE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAC5E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAErE,MAAM,CAAC,OAAO,OAAO,eAAe;IACtB,OAAO,CAAC,QAAQ,CAAC,YAAY;gBAAZ,YAAY,EAAE,YAAY;IAEjD,IAAI,CACR,OAAO,GAAE;QACP,GAAG,CAAC,EAAE,OAAO,CAAC;QACd,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,IAAI,CAAC,EAAE,OAAO,CAAC;QACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;KACiB;IAkBlD,GAAG,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,GAAE,OAAe;IAQ9C,GAAG,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,GAAE,MAAc;IAQ/C,IAAI,CACR,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE;QACP,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,IAAI,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;KASvB;IAqBG,KAAK,CACT,WAAW,EAAE,MAAM,EACnB,OAAO,GACH;QAAE,MAAM,EAAE,IAAI,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAE,GACjC;QACE,MAAM,EAAE,KAAK,CAAC;QACd,OAAO,CAAC,EAAE,OAAO,CAAC;KAIvB;CAeJ"}
@@ -0,0 +1,58 @@
1
+ import DockerSocket from "./DockerSocket";
2
+ export default class DockerContainer {
3
+ dockerSocket;
4
+ constructor(dockerSocket) {
5
+ this.dockerSocket = dockerSocket;
6
+ }
7
+ async list(options = { all: false, limit: 0, size: false, filters: {} }) {
8
+ const apiOptions = {
9
+ all: (options.all ?? false).toString(),
10
+ limit: (options.limit ?? 0).toString(),
11
+ size: (options.size ?? false).toString(),
12
+ filters: JSON.stringify(options.filters ?? {}),
13
+ };
14
+ return await this.dockerSocket.apiCall("GET", "/containers/json", {
15
+ query: apiOptions,
16
+ });
17
+ }
18
+ async get(containerId, size = false) {
19
+ return await this.dockerSocket.apiCall("GET", `/containers/${containerId}/json`, { query: { size: size.toString() } });
20
+ }
21
+ async top(containerId, psArgs = "-ef") {
22
+ return await this.dockerSocket.apiCall("GET", `/containers/${containerId}/top`, { query: { psArgs: psArgs } });
23
+ }
24
+ async logs(containerId, options = {
25
+ follow: false,
26
+ stdout: false,
27
+ stderr: false,
28
+ since: 0,
29
+ until: 0,
30
+ timestamps: false,
31
+ tail: "all",
32
+ }) {
33
+ const apiOptions = {
34
+ follow: (options?.follow ?? false).toString(),
35
+ stdout: (options?.stdout ?? false).toString(),
36
+ stderr: (options?.stderr ?? false).toString(),
37
+ since: (options?.since ?? 0).toString(),
38
+ until: (options?.until ?? 0).toString(),
39
+ timestamps: (options?.timestamps ?? false).toString(),
40
+ tail: (options?.tail ?? "all").toString(),
41
+ };
42
+ return await this.dockerSocket.apiCall("GET", `/containers/${containerId}/logs`, {
43
+ query: apiOptions,
44
+ });
45
+ }
46
+ async stats(containerId, options = {
47
+ stream: true,
48
+ oneShot: false,
49
+ }) {
50
+ const apiOptions = {
51
+ stream: (options.stream ?? true).toString(),
52
+ "one-shot": (options.oneShot ?? false).toString(),
53
+ };
54
+ return await this.dockerSocket.apiCall("GET", `/containers/${containerId}/stats`, {
55
+ query: apiOptions,
56
+ });
57
+ }
58
+ }
@@ -14,6 +14,7 @@ export default class DockerSocket {
14
14
  apiCall<T>(method: Request["method"], urlPath: string, options?: {
15
15
  headers?: Record<string, string>;
16
16
  body?: string | Buffer | DataView;
17
+ query?: Record<string, string>;
17
18
  }): Promise<T>;
18
19
  authenticate(serverAddress: string, username: string, password: string): Promise<void>;
19
20
  info(): Promise<DockerInfo>;
@@ -1 +1 @@
1
- {"version":3,"file":"DockerSocket.d.ts","sourceRoot":"","sources":["../src/DockerSocket.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAQrD,MAAM,CAAC,OAAO,OAAO,YAAY;IAS7B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAR7B,OAAO,CAAC,gBAAgB,CAAS;IAEjC,OAAO,CAAC,aAAa,CAA8B;IAEnD,OAAO,CAAC,eAAe,CAAuB;gBAG5C,cAAc,GAAE,MAA+B,EAC9B,UAAU,GAAE,MAA2B;IAKpD,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC;YAiBnB,OAAO;IA+Df,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAa3B,IAAI,OAAO,kBAKV;IAED,IAAI,KAAK,WAKR;IAEK,OAAO,CAAC,CAAC,EACb,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,EACzB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QACR,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACjC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAC;KACnC,GACA,OAAO,CAAC,CAAC,CAAC;IAYP,YAAY,CAChB,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;IAoBV,IAAI,IAAI,OAAO,CAAC,UAAU,CAAC;CAGlC"}
1
+ {"version":3,"file":"DockerSocket.d.ts","sourceRoot":"","sources":["../src/DockerSocket.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAQrD,MAAM,CAAC,OAAO,OAAO,YAAY;IAS7B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAR7B,OAAO,CAAC,gBAAgB,CAAS;IAEjC,OAAO,CAAC,aAAa,CAA8B;IAEnD,OAAO,CAAC,eAAe,CAAuB;gBAG5C,cAAc,GAAE,MAA+B,EAC9B,UAAU,GAAE,MAA2B;IAKpD,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC;YAiBnB,OAAO;IAqEf,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAa3B,IAAI,OAAO,kBAKV;IAED,IAAI,KAAK,WAKR;IAEK,OAAO,CAAC,CAAC,EACb,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,EACzB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QACR,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACjC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAC;QAClC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KAChC,GACA,OAAO,CAAC,CAAC,CAAC;IAkBP,YAAY,CAChB,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;IAmBV,IAAI,IAAI,OAAO,CAAC,UAAU,CAAC;CAGlC"}
@@ -26,12 +26,17 @@ export default class DockerSocket {
26
26
  }
27
27
  async request(method, path, options) {
28
28
  const url = new URL(path, this.apiBaseURL);
29
+ if (options?.query) {
30
+ for (const [k, v] of Object.entries(options.query)) {
31
+ url.searchParams.set(k, v);
32
+ }
33
+ }
29
34
  const requestOptions = {
30
35
  hostname: url.hostname,
31
36
  host: url.host,
32
37
  protocol: url.protocol,
33
38
  port: url.port,
34
- path: url.pathname,
39
+ path: url.pathname + url.search.toString(),
35
40
  headers: options?.headers,
36
41
  method: method,
37
42
  socketPath: this.dockerSocketPath,
@@ -85,8 +90,14 @@ export default class DockerSocket {
85
90
  }
86
91
  async apiCall(method, urlPath, options) {
87
92
  const { ApiVersion } = this.version;
88
- const response = await this.request(method, path.join("/", `v${ApiVersion}`, urlPath), options);
89
- return JSON.parse(response.body.toString("utf-8"));
93
+ const response = await this.request(method, `/v${ApiVersion}/${urlPath.replace(/^\//, "")}`, options);
94
+ const responseBody = response.body.toString("utf-8");
95
+ try {
96
+ return JSON.parse(responseBody);
97
+ }
98
+ catch {
99
+ return responseBody;
100
+ }
90
101
  }
91
102
  async authenticate(serverAddress, username, password) {
92
103
  const tokenPayload = JSON.stringify({ serverAddress, username, password });
package/dist/index.js CHANGED
@@ -1,12 +1,19 @@
1
+ import DockerContainer from "./DockerContainer";
1
2
  import DockerSocket from "./DockerSocket";
2
3
  (async function () {
3
4
  const socket = new DockerSocket();
4
5
  await socket.init();
5
- console.log(await socket.info());
6
6
  // await socket.authenticate(
7
7
  // "ghcr.io",
8
8
  // "github_username",
9
9
  // "github_pat",
10
10
  // );
11
11
  // console.log(socket.token);
12
+ // console.log(await socket.info());
13
+ const containersApi = new DockerContainer(socket);
14
+ const containersSummary = await containersApi.stats("XXX", {
15
+ stream: false,
16
+ oneShot: true,
17
+ });
18
+ console.log(containersSummary);
12
19
  })();
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@hallmaster/docker.js",
3
3
  "description": "A TypeScript Docker API wrapper mainly used for the Hallmaster project.",
4
- "version": "0.0.5",
4
+ "version": "0.0.7",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "private": false,
@@ -15,6 +15,7 @@
15
15
  "dist"
16
16
  ],
17
17
  "repository": "github:hallmasterorg/hallmaster-docker-wrapper",
18
+ "homepage": "https://github.com/hallmasterorg/hallmaster-docker-wrapper#readme",
18
19
  "devDependencies": {
19
20
  "@types/node": "^25.0.9",
20
21
  "typescript": "^5.9.3"