@ostanin/podman 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.
Files changed (142) hide show
  1. package/README.md +432 -0
  2. package/esm/_dnt.polyfills.d.ts +7 -0
  3. package/esm/_dnt.polyfills.d.ts.map +1 -0
  4. package/esm/_dnt.polyfills.js +1 -0
  5. package/esm/api/artifacts.d.ts +25 -0
  6. package/esm/api/artifacts.d.ts.map +1 -0
  7. package/esm/api/artifacts.js +89 -0
  8. package/esm/api/containers.d.ts +71 -0
  9. package/esm/api/containers.d.ts.map +1 -0
  10. package/esm/api/containers.js +234 -0
  11. package/esm/api/exec.d.ts +15 -0
  12. package/esm/api/exec.d.ts.map +1 -0
  13. package/esm/api/exec.js +45 -0
  14. package/esm/api/generate.d.ts +11 -0
  15. package/esm/api/generate.d.ts.map +1 -0
  16. package/esm/api/generate.js +24 -0
  17. package/esm/api/images.d.ts +55 -0
  18. package/esm/api/images.d.ts.map +1 -0
  19. package/esm/api/images.js +212 -0
  20. package/esm/api/kube.d.ts +13 -0
  21. package/esm/api/kube.d.ts.map +1 -0
  22. package/esm/api/kube.js +38 -0
  23. package/esm/api/manifests.d.ts +19 -0
  24. package/esm/api/manifests.d.ts.map +1 -0
  25. package/esm/api/manifests.js +60 -0
  26. package/esm/api/networks.d.ts +25 -0
  27. package/esm/api/networks.d.ts.map +1 -0
  28. package/esm/api/networks.js +95 -0
  29. package/esm/api/pods.d.ts +35 -0
  30. package/esm/api/pods.d.ts.map +1 -0
  31. package/esm/api/pods.js +120 -0
  32. package/esm/api/quadlets.d.ts +23 -0
  33. package/esm/api/quadlets.d.ts.map +1 -0
  34. package/esm/api/quadlets.js +56 -0
  35. package/esm/api/secrets.d.ts +17 -0
  36. package/esm/api/secrets.d.ts.map +1 -0
  37. package/esm/api/secrets.js +49 -0
  38. package/esm/api/system.d.ts +23 -0
  39. package/esm/api/system.d.ts.map +1 -0
  40. package/esm/api/system.js +98 -0
  41. package/esm/api/volumes.d.ts +23 -0
  42. package/esm/api/volumes.d.ts.map +1 -0
  43. package/esm/api/volumes.js +69 -0
  44. package/esm/client.d.ts +56 -0
  45. package/esm/client.d.ts.map +1 -0
  46. package/esm/client.js +63 -0
  47. package/esm/internal/query.d.ts +2 -0
  48. package/esm/internal/query.d.ts.map +1 -0
  49. package/esm/internal/query.js +24 -0
  50. package/esm/mod.d.ts +22 -0
  51. package/esm/mod.d.ts.map +1 -0
  52. package/esm/mod.js +18 -0
  53. package/esm/package.json +3 -0
  54. package/esm/ssh_transport.d.ts +14 -0
  55. package/esm/ssh_transport.d.ts.map +1 -0
  56. package/esm/ssh_transport.js +85 -0
  57. package/esm/transport.d.ts +23 -0
  58. package/esm/transport.d.ts.map +1 -0
  59. package/esm/transport.js +112 -0
  60. package/esm/transport_core.d.ts +31 -0
  61. package/esm/transport_core.d.ts.map +1 -0
  62. package/esm/transport_core.js +75 -0
  63. package/esm/types/api.d.ts +61 -0
  64. package/esm/types/api.d.ts.map +1 -0
  65. package/esm/types/api.js +5 -0
  66. package/esm/types/errors.d.ts +21 -0
  67. package/esm/types/errors.d.ts.map +1 -0
  68. package/esm/types/errors.js +47 -0
  69. package/esm/types/openapi.d.ts +19552 -0
  70. package/esm/types/openapi.d.ts.map +1 -0
  71. package/esm/types/openapi.js +5 -0
  72. package/package.json +36 -0
  73. package/script/_dnt.polyfills.d.ts +7 -0
  74. package/script/_dnt.polyfills.d.ts.map +1 -0
  75. package/script/_dnt.polyfills.js +2 -0
  76. package/script/api/artifacts.d.ts +25 -0
  77. package/script/api/artifacts.d.ts.map +1 -0
  78. package/script/api/artifacts.js +93 -0
  79. package/script/api/containers.d.ts +71 -0
  80. package/script/api/containers.d.ts.map +1 -0
  81. package/script/api/containers.js +238 -0
  82. package/script/api/exec.d.ts +15 -0
  83. package/script/api/exec.d.ts.map +1 -0
  84. package/script/api/exec.js +49 -0
  85. package/script/api/generate.d.ts +11 -0
  86. package/script/api/generate.d.ts.map +1 -0
  87. package/script/api/generate.js +28 -0
  88. package/script/api/images.d.ts +55 -0
  89. package/script/api/images.d.ts.map +1 -0
  90. package/script/api/images.js +216 -0
  91. package/script/api/kube.d.ts +13 -0
  92. package/script/api/kube.d.ts.map +1 -0
  93. package/script/api/kube.js +42 -0
  94. package/script/api/manifests.d.ts +19 -0
  95. package/script/api/manifests.d.ts.map +1 -0
  96. package/script/api/manifests.js +64 -0
  97. package/script/api/networks.d.ts +25 -0
  98. package/script/api/networks.d.ts.map +1 -0
  99. package/script/api/networks.js +99 -0
  100. package/script/api/pods.d.ts +35 -0
  101. package/script/api/pods.d.ts.map +1 -0
  102. package/script/api/pods.js +124 -0
  103. package/script/api/quadlets.d.ts +23 -0
  104. package/script/api/quadlets.d.ts.map +1 -0
  105. package/script/api/quadlets.js +60 -0
  106. package/script/api/secrets.d.ts +17 -0
  107. package/script/api/secrets.d.ts.map +1 -0
  108. package/script/api/secrets.js +53 -0
  109. package/script/api/system.d.ts +23 -0
  110. package/script/api/system.d.ts.map +1 -0
  111. package/script/api/system.js +102 -0
  112. package/script/api/volumes.d.ts +23 -0
  113. package/script/api/volumes.d.ts.map +1 -0
  114. package/script/api/volumes.js +73 -0
  115. package/script/client.d.ts +56 -0
  116. package/script/client.d.ts.map +1 -0
  117. package/script/client.js +67 -0
  118. package/script/internal/query.d.ts +2 -0
  119. package/script/internal/query.d.ts.map +1 -0
  120. package/script/internal/query.js +27 -0
  121. package/script/mod.d.ts +22 -0
  122. package/script/mod.d.ts.map +1 -0
  123. package/script/mod.js +42 -0
  124. package/script/package.json +3 -0
  125. package/script/ssh_transport.d.ts +14 -0
  126. package/script/ssh_transport.d.ts.map +1 -0
  127. package/script/ssh_transport.js +121 -0
  128. package/script/transport.d.ts +23 -0
  129. package/script/transport.d.ts.map +1 -0
  130. package/script/transport.js +149 -0
  131. package/script/transport_core.d.ts +31 -0
  132. package/script/transport_core.d.ts.map +1 -0
  133. package/script/transport_core.js +78 -0
  134. package/script/types/api.d.ts +61 -0
  135. package/script/types/api.d.ts.map +1 -0
  136. package/script/types/api.js +6 -0
  137. package/script/types/errors.d.ts +21 -0
  138. package/script/types/errors.d.ts.map +1 -0
  139. package/script/types/errors.js +54 -0
  140. package/script/types/openapi.d.ts +19552 -0
  141. package/script/types/openapi.d.ts.map +1 -0
  142. package/script/types/openapi.js +6 -0
@@ -0,0 +1,98 @@
1
+ import { createPodmanError } from "../types/errors.js";
2
+ import { buildQuery } from "../internal/query.js";
3
+ export class SystemApi {
4
+ #t;
5
+ constructor(transport) {
6
+ this.#t = transport;
7
+ }
8
+ /** Return information about the Podman host. */
9
+ async info() {
10
+ const path = "/info";
11
+ const { status, json } = await this.#t.request("GET", path);
12
+ if (status !== 200)
13
+ throw createPodmanError(status, json, "GET", path);
14
+ return json;
15
+ }
16
+ /** Return component version information for the Podman service. */
17
+ async version() {
18
+ const path = "/version";
19
+ const { status, json } = await this.#t.request("GET", path);
20
+ if (status !== 200)
21
+ throw createPodmanError(status, json, "GET", path);
22
+ return json;
23
+ }
24
+ /** Ping the Podman service. Returns `true` if reachable. */
25
+ async ping() {
26
+ // /_ping returns plain text "OK", not JSON — use requestRaw
27
+ const res = await this.#t.requestRaw("GET", "/_ping");
28
+ await res.body?.cancel();
29
+ return res.status === 200;
30
+ }
31
+ /** Prune unused data (containers, images, volumes, networks). */
32
+ async prune() {
33
+ const path = "/system/prune";
34
+ const { status, json } = await this.#t.request("POST", path);
35
+ if (status !== 200)
36
+ throw createPodmanError(status, json, "POST", path);
37
+ return json;
38
+ }
39
+ /** Return disk usage information (containers, images, volumes). */
40
+ async df() {
41
+ const path = "/system/df";
42
+ const { status, json } = await this.#t.request("GET", path);
43
+ if (status !== 200)
44
+ throw createPodmanError(status, json, "GET", path);
45
+ return json;
46
+ }
47
+ /** Stream system events as raw bytes. */
48
+ async events(query) {
49
+ const path = `/events${buildQuery(query)}`;
50
+ return await this.#t.requestStream("GET", path);
51
+ }
52
+ /** Stream system events as parsed JSON objects. */
53
+ async *parsedEvents(query) {
54
+ const stream = await this.events(query);
55
+ const reader = stream.pipeThrough(new TextDecoderStream()).getReader();
56
+ let buffer = "";
57
+ try {
58
+ while (true) {
59
+ const { done, value } = await reader.read();
60
+ if (done)
61
+ break;
62
+ buffer += value;
63
+ const lines = buffer.split("\n");
64
+ buffer = lines.pop() ?? "";
65
+ for (const line of lines) {
66
+ const trimmed = line.trim();
67
+ if (trimmed) {
68
+ try {
69
+ yield JSON.parse(trimmed);
70
+ }
71
+ catch {
72
+ // Skip malformed JSON lines (e.g. truncated stream)
73
+ }
74
+ }
75
+ }
76
+ }
77
+ if (buffer.trim()) {
78
+ try {
79
+ yield JSON.parse(buffer.trim());
80
+ }
81
+ catch {
82
+ // Skip malformed trailing data
83
+ }
84
+ }
85
+ }
86
+ finally {
87
+ reader.releaseLock();
88
+ }
89
+ }
90
+ /** Run a consistency check on container storage. */
91
+ async check(query) {
92
+ const path = `/system/check${buildQuery(query)}`;
93
+ const { status, json } = await this.#t.request("POST", path);
94
+ if (status !== 200)
95
+ throw createPodmanError(status, json, "POST", path);
96
+ return json;
97
+ }
98
+ }
@@ -0,0 +1,23 @@
1
+ import type { Transport } from "../transport.js";
2
+ import type { VolumeConfigResponse, VolumeCreateOptions, VolumeRemoveQuery, VolumeListQuery, VolumePruneQuery, VolumePruneReport } from "../types/api.js";
3
+ export declare class VolumesApi {
4
+ #private;
5
+ constructor(transport: Transport);
6
+ /** Create a new volume. */
7
+ create(opts: VolumeCreateOptions): Promise<VolumeConfigResponse>;
8
+ /** Inspect a volume. Returns `null` if the volume is not found. */
9
+ inspect(nameOrId: string): Promise<VolumeConfigResponse | null>;
10
+ /** List volumes, optionally filtered by the given query. */
11
+ list(query?: VolumeListQuery): Promise<VolumeConfigResponse[]>;
12
+ /** Remove a volume. */
13
+ remove(nameOrId: string, query?: VolumeRemoveQuery): Promise<void>;
14
+ /** Check if a volume exists. Returns `true` on 204, `false` otherwise. */
15
+ exists(nameOrId: string): Promise<boolean>;
16
+ /** Remove unused volumes. Returns a list of pruned volumes. */
17
+ prune(query?: VolumePruneQuery): Promise<VolumePruneReport[]>;
18
+ /** Export a volume as a tar archive stream. */
19
+ export(nameOrId: string): Promise<ReadableStream<Uint8Array>>;
20
+ /** Import a tar archive into a volume. */
21
+ import(nameOrId: string, body: ReadableStream<Uint8Array>): Promise<void>;
22
+ }
23
+ //# sourceMappingURL=volumes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"volumes.d.ts","sourceRoot":"","sources":["../../src/api/volumes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAGjD,OAAO,KAAK,EACV,oBAAoB,EACpB,mBAAmB,EACnB,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EAClB,MAAM,iBAAiB,CAAC;AAEzB,qBAAa,UAAU;;gBAET,SAAS,EAAE,SAAS;IAIhC,2BAA2B;IACrB,MAAM,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAOtE,mEAAmE;IAC7D,OAAO,CACX,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IAQvC,4DAA4D;IACtD,IAAI,CAAC,KAAK,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,oBAAoB,EAAE,CAAC;IAOpE,uBAAuB;IACjB,MAAM,CACV,QAAQ,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,iBAAiB,GACxB,OAAO,CAAC,IAAI,CAAC;IAOhB,0EAA0E;IACpE,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAMhD,+DAA+D;IACzD,KAAK,CAAC,KAAK,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAOnE,+CAA+C;IACzC,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;IAKnE,0CAA0C;IACpC,MAAM,CACV,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,cAAc,CAAC,UAAU,CAAC,GAC/B,OAAO,CAAC,IAAI,CAAC;CAOjB"}
@@ -0,0 +1,69 @@
1
+ import { createPodmanError, throwRawError } from "../types/errors.js";
2
+ import { buildQuery } from "../internal/query.js";
3
+ export class VolumesApi {
4
+ #t;
5
+ constructor(transport) {
6
+ this.#t = transport;
7
+ }
8
+ /** Create a new volume. */
9
+ async create(opts) {
10
+ const path = "/volumes/create";
11
+ const { status, json } = await this.#t.request("POST", path, opts);
12
+ if (status !== 201)
13
+ throw createPodmanError(status, json, "POST", path);
14
+ return json;
15
+ }
16
+ /** Inspect a volume. Returns `null` if the volume is not found. */
17
+ async inspect(nameOrId) {
18
+ const path = `/volumes/${encodeURIComponent(nameOrId)}/json`;
19
+ const { status, json } = await this.#t.request("GET", path);
20
+ if (status === 404)
21
+ return null;
22
+ if (status !== 200)
23
+ throw createPodmanError(status, json, "GET", path);
24
+ return json;
25
+ }
26
+ /** List volumes, optionally filtered by the given query. */
27
+ async list(query) {
28
+ const path = `/volumes/json${buildQuery(query)}`;
29
+ const { status, json } = await this.#t.request("GET", path);
30
+ if (status !== 200)
31
+ throw createPodmanError(status, json, "GET", path);
32
+ return (json ?? []);
33
+ }
34
+ /** Remove a volume. */
35
+ async remove(nameOrId, query) {
36
+ const path = `/volumes/${encodeURIComponent(nameOrId)}${buildQuery(query)}`;
37
+ const { status, json } = await this.#t.request("DELETE", path);
38
+ if (status !== 204)
39
+ throw createPodmanError(status, json, "DELETE", path);
40
+ }
41
+ /** Check if a volume exists. Returns `true` on 204, `false` otherwise. */
42
+ async exists(nameOrId) {
43
+ const path = `/volumes/${encodeURIComponent(nameOrId)}/exists`;
44
+ const { status } = await this.#t.request("GET", path);
45
+ return status === 204;
46
+ }
47
+ /** Remove unused volumes. Returns a list of pruned volumes. */
48
+ async prune(query) {
49
+ const path = `/volumes/prune${buildQuery(query)}`;
50
+ const { status, json } = await this.#t.request("POST", path);
51
+ if (status !== 200)
52
+ throw createPodmanError(status, json, "POST", path);
53
+ return (json ?? []);
54
+ }
55
+ /** Export a volume as a tar archive stream. */
56
+ async export(nameOrId) {
57
+ const path = `/volumes/${encodeURIComponent(nameOrId)}/export`;
58
+ return await this.#t.requestStream("GET", path);
59
+ }
60
+ /** Import a tar archive into a volume. */
61
+ async import(nameOrId, body) {
62
+ const path = `/volumes/${encodeURIComponent(nameOrId)}/import`;
63
+ const res = await this.#t.requestRaw("POST", path, body, {
64
+ "Content-Type": "application/x-tar",
65
+ });
66
+ if (res.status !== 204)
67
+ await throwRawError(res, "POST", path);
68
+ }
69
+ }
@@ -0,0 +1,56 @@
1
+ import { type TlsOptions } from "./transport.js";
2
+ import { type SshTransportOptions } from "./ssh_transport.js";
3
+ import type { AuthOption } from "./transport_core.js";
4
+ import { ContainersApi } from "./api/containers.js";
5
+ import { ImagesApi } from "./api/images.js";
6
+ import { NetworksApi } from "./api/networks.js";
7
+ import { VolumesApi } from "./api/volumes.js";
8
+ import { PodsApi } from "./api/pods.js";
9
+ import { SecretsApi } from "./api/secrets.js";
10
+ import { SystemApi } from "./api/system.js";
11
+ import { ExecApi } from "./api/exec.js";
12
+ import { GenerateApi } from "./api/generate.js";
13
+ import { ManifestsApi } from "./api/manifests.js";
14
+ import { KubeApi } from "./api/kube.js";
15
+ import { ArtifactsApi } from "./api/artifacts.js";
16
+ import { QuadletsApi } from "./api/quadlets.js";
17
+ /** Options for connecting to Podman via a Unix socket. */
18
+ export interface UnixClientOptions {
19
+ socketPath: string;
20
+ apiVersion?: string;
21
+ timeout?: number;
22
+ auth?: AuthOption;
23
+ }
24
+ /** Options for connecting to Podman via TCP or TLS. */
25
+ export interface TcpClientOptions {
26
+ uri: string;
27
+ apiVersion?: string;
28
+ timeout?: number;
29
+ auth?: AuthOption;
30
+ tls?: TlsOptions;
31
+ }
32
+ /** Union of all client connection options (Unix socket or TCP/TLS). */
33
+ export type ClientOptions = UnixClientOptions | TcpClientOptions;
34
+ export type SshClientOptions = SshTransportOptions;
35
+ /** Client interface exposing all 13 Podman libpod API modules. */
36
+ export interface PodmanClient {
37
+ containers: ContainersApi;
38
+ images: ImagesApi;
39
+ networks: NetworksApi;
40
+ volumes: VolumesApi;
41
+ pods: PodsApi;
42
+ secrets: SecretsApi;
43
+ system: SystemApi;
44
+ exec: ExecApi;
45
+ generate: GenerateApi;
46
+ manifests: ManifestsApi;
47
+ kube: KubeApi;
48
+ artifacts: ArtifactsApi;
49
+ quadlets: QuadletsApi;
50
+ close(): void;
51
+ }
52
+ /** Create a Podman client using a Unix socket or TCP/TLS connection. */
53
+ export declare function createClient(opts: ClientOptions): PodmanClient;
54
+ /** Create a Podman client tunneled over SSH. Requires `ssh` on the local machine. */
55
+ export declare function createSshClient(opts: SshClientOptions): Promise<PodmanClient>;
56
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,UAAU,EAGhB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAEL,KAAK,mBAAmB,EACzB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,0DAA0D;AAC1D,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB;AAED,uDAAuD;AACvD,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,GAAG,CAAC,EAAE,UAAU,CAAC;CAClB;AAED,uEAAuE;AACvE,MAAM,MAAM,aAAa,GAAG,iBAAiB,GAAG,gBAAgB,CAAC;AAEjE,MAAM,MAAM,gBAAgB,GAAG,mBAAmB,CAAC;AAEnD,kEAAkE;AAClE,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,aAAa,CAAC;IAC1B,MAAM,EAAE,SAAS,CAAC;IAClB,QAAQ,EAAE,WAAW,CAAC;IACtB,OAAO,EAAE,UAAU,CAAC;IACpB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,UAAU,CAAC;IACpB,MAAM,EAAE,SAAS,CAAC;IAClB,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,WAAW,CAAC;IACtB,SAAS,EAAE,YAAY,CAAC;IACxB,IAAI,EAAE,OAAO,CAAC;IACd,SAAS,EAAE,YAAY,CAAC;IACxB,QAAQ,EAAE,WAAW,CAAC;IACtB,KAAK,IAAI,IAAI,CAAC;CACf;AAuBD,wEAAwE;AACxE,wBAAgB,YAAY,CAAC,IAAI,EAAE,aAAa,GAAG,YAAY,CAsB9D;AAED,qFAAqF;AACrF,wBAAsB,eAAe,CACnC,IAAI,EAAE,gBAAgB,GACrB,OAAO,CAAC,YAAY,CAAC,CAGvB"}
package/esm/client.js ADDED
@@ -0,0 +1,63 @@
1
+ import { createTcpTransport, createTransport, } from "./transport.js";
2
+ import { createSshTransport, } from "./ssh_transport.js";
3
+ import { ContainersApi } from "./api/containers.js";
4
+ import { ImagesApi } from "./api/images.js";
5
+ import { NetworksApi } from "./api/networks.js";
6
+ import { VolumesApi } from "./api/volumes.js";
7
+ import { PodsApi } from "./api/pods.js";
8
+ import { SecretsApi } from "./api/secrets.js";
9
+ import { SystemApi } from "./api/system.js";
10
+ import { ExecApi } from "./api/exec.js";
11
+ import { GenerateApi } from "./api/generate.js";
12
+ import { ManifestsApi } from "./api/manifests.js";
13
+ import { KubeApi } from "./api/kube.js";
14
+ import { ArtifactsApi } from "./api/artifacts.js";
15
+ import { QuadletsApi } from "./api/quadlets.js";
16
+ function buildPodmanClient(transport) {
17
+ return {
18
+ containers: new ContainersApi(transport),
19
+ images: new ImagesApi(transport),
20
+ networks: new NetworksApi(transport),
21
+ volumes: new VolumesApi(transport),
22
+ pods: new PodsApi(transport),
23
+ secrets: new SecretsApi(transport),
24
+ system: new SystemApi(transport),
25
+ exec: new ExecApi(transport),
26
+ generate: new GenerateApi(transport),
27
+ manifests: new ManifestsApi(transport),
28
+ kube: new KubeApi(transport),
29
+ artifacts: new ArtifactsApi(transport),
30
+ quadlets: new QuadletsApi(transport),
31
+ close() {
32
+ transport.close();
33
+ },
34
+ };
35
+ }
36
+ /** Create a Podman client using a Unix socket or TCP/TLS connection. */
37
+ export function createClient(opts) {
38
+ let transport;
39
+ if ("socketPath" in opts) {
40
+ const transportOpts = {
41
+ socketPath: opts.socketPath,
42
+ apiVersion: opts.apiVersion,
43
+ timeout: opts.timeout,
44
+ auth: opts.auth,
45
+ };
46
+ transport = createTransport(transportOpts);
47
+ }
48
+ else {
49
+ transport = createTcpTransport({
50
+ uri: opts.uri,
51
+ apiVersion: opts.apiVersion,
52
+ timeout: opts.timeout,
53
+ auth: opts.auth,
54
+ tls: opts.tls,
55
+ });
56
+ }
57
+ return buildPodmanClient(transport);
58
+ }
59
+ /** Create a Podman client tunneled over SSH. Requires `ssh` on the local machine. */
60
+ export async function createSshClient(opts) {
61
+ const transport = await createSshTransport(opts);
62
+ return buildPodmanClient(transport);
63
+ }
@@ -0,0 +1,2 @@
1
+ export declare function buildQuery<T extends object>(params?: T): string;
2
+ //# sourceMappingURL=query.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../src/internal/query.ts"],"names":[],"mappings":"AAAA,wBAAgB,UAAU,CAAC,CAAC,SAAS,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,GAAG,MAAM,CA0B/D"}
@@ -0,0 +1,24 @@
1
+ export function buildQuery(params) {
2
+ if (!params)
3
+ return "";
4
+ const entries = Object.entries(params).filter(([_, v]) => v !== undefined);
5
+ if (entries.length === 0)
6
+ return "";
7
+ const parts = [];
8
+ for (const [k, v] of entries) {
9
+ if (Array.isArray(v)) {
10
+ // Arrays → repeated query params: ?names=foo&names=bar
11
+ for (const item of v) {
12
+ parts.push(`${encodeURIComponent(k)}=${encodeURIComponent(String(item))}`);
13
+ }
14
+ }
15
+ else if (typeof v === "object" && v !== null) {
16
+ // Objects (e.g. filters) → JSON-encoded
17
+ parts.push(`${encodeURIComponent(k)}=${encodeURIComponent(JSON.stringify(v))}`);
18
+ }
19
+ else {
20
+ parts.push(`${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`);
21
+ }
22
+ }
23
+ return parts.length > 0 ? `?${parts.join("&")}` : "";
24
+ }
package/esm/mod.d.ts ADDED
@@ -0,0 +1,22 @@
1
+ import "./_dnt.polyfills.js";
2
+ export { type ClientOptions, createClient, createSshClient, type PodmanClient, type SshClientOptions, type TcpClientOptions, type UnixClientOptions, } from "./client.js";
3
+ export { PodmanError, createPodmanError, throwRawError } from "./types/errors.js";
4
+ export { createTcpTransport, createTransport, type TcpTransportOptions, type TlsOptions, type Transport, type TransportOptions, type TransportResponse, } from "./transport.js";
5
+ export { createSshTransport, type SshTransportOptions, } from "./ssh_transport.js";
6
+ export type { AuthOption } from "./transport_core.js";
7
+ export type * from "./types/api.js";
8
+ export { ContainersApi } from "./api/containers.js";
9
+ export { ImagesApi } from "./api/images.js";
10
+ export { NetworksApi } from "./api/networks.js";
11
+ export { VolumesApi } from "./api/volumes.js";
12
+ export { PodsApi } from "./api/pods.js";
13
+ export { SecretsApi } from "./api/secrets.js";
14
+ export { SystemApi } from "./api/system.js";
15
+ export { ExecApi } from "./api/exec.js";
16
+ export { GenerateApi } from "./api/generate.js";
17
+ export { ManifestsApi } from "./api/manifests.js";
18
+ export { KubeApi } from "./api/kube.js";
19
+ export { ArtifactsApi } from "./api/artifacts.js";
20
+ export { QuadletsApi } from "./api/quadlets.js";
21
+ export type { QuadletInstallReport } from "./api/quadlets.js";
22
+ //# sourceMappingURL=mod.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../src/mod.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAC7B,OAAO,EACL,KAAK,aAAa,EAClB,YAAY,EACZ,eAAe,EACf,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,GACvB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClF,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,KAAK,mBAAmB,EACxB,KAAK,UAAU,EACf,KAAK,SAAS,EACd,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,GACvB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,kBAAkB,EAClB,KAAK,mBAAmB,GACzB,MAAM,oBAAoB,CAAC;AAE5B,YAAY,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAItD,mBAAmB,gBAAgB,CAAC;AAEpC,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,YAAY,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC"}
package/esm/mod.js ADDED
@@ -0,0 +1,18 @@
1
+ import "./_dnt.polyfills.js";
2
+ export { createClient, createSshClient, } from "./client.js";
3
+ export { PodmanError, createPodmanError, throwRawError } from "./types/errors.js";
4
+ export { createTcpTransport, createTransport, } from "./transport.js";
5
+ export { createSshTransport, } from "./ssh_transport.js";
6
+ export { ContainersApi } from "./api/containers.js";
7
+ export { ImagesApi } from "./api/images.js";
8
+ export { NetworksApi } from "./api/networks.js";
9
+ export { VolumesApi } from "./api/volumes.js";
10
+ export { PodsApi } from "./api/pods.js";
11
+ export { SecretsApi } from "./api/secrets.js";
12
+ export { SystemApi } from "./api/system.js";
13
+ export { ExecApi } from "./api/exec.js";
14
+ export { GenerateApi } from "./api/generate.js";
15
+ export { ManifestsApi } from "./api/manifests.js";
16
+ export { KubeApi } from "./api/kube.js";
17
+ export { ArtifactsApi } from "./api/artifacts.js";
18
+ export { QuadletsApi } from "./api/quadlets.js";
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "module"
3
+ }
@@ -0,0 +1,14 @@
1
+ import { type Transport } from "./transport.js";
2
+ import type { AuthOption } from "./transport_core.js";
3
+ export interface SshTransportOptions {
4
+ host: string;
5
+ remoteSocketPath?: string;
6
+ port?: number;
7
+ identityFile?: string;
8
+ sshOptions?: string[];
9
+ apiVersion?: string;
10
+ timeout?: number;
11
+ auth?: AuthOption;
12
+ }
13
+ export declare function createSshTransport(opts: SshTransportOptions): Promise<Transport>;
14
+ //# sourceMappingURL=ssh_transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ssh_transport.d.ts","sourceRoot":"","sources":["../src/ssh_transport.ts"],"names":[],"mappings":"AAIA,OAAO,EAAmB,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEjE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEtD,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB;AAWD,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,mBAAmB,GACxB,OAAO,CAAC,SAAS,CAAC,CAyFpB"}
@@ -0,0 +1,85 @@
1
+ import { spawn } from "node:child_process";
2
+ import * as fs from "node:fs/promises";
3
+ import * as os from "node:os";
4
+ import * as path from "node:path";
5
+ import { createTransport } from "./transport.js";
6
+ async function drainStderr(child) {
7
+ if (!child.stderr)
8
+ return "";
9
+ const chunks = [];
10
+ for await (const chunk of child.stderr) {
11
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
12
+ }
13
+ return Buffer.concat(chunks).toString("utf8");
14
+ }
15
+ export async function createSshTransport(opts) {
16
+ const { host, remoteSocketPath = "/run/podman/podman.sock", port = 22, identityFile, sshOptions = [], apiVersion, timeout, auth, } = opts;
17
+ const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "podman-deno-"));
18
+ const localSocket = path.join(tempDir, "podman.sock");
19
+ const hasStrictHostKeyChecking = sshOptions.some((o) => o.includes("StrictHostKeyChecking"));
20
+ const args = [
21
+ "-N",
22
+ "-L", `${localSocket}:${remoteSocketPath}`,
23
+ "-p", String(port),
24
+ ...(hasStrictHostKeyChecking
25
+ ? []
26
+ : ["-o", "StrictHostKeyChecking=accept-new"]),
27
+ "-o", "ExitOnForwardFailure=yes",
28
+ ];
29
+ if (identityFile)
30
+ args.push("-i", identityFile);
31
+ args.push(...sshOptions, host);
32
+ const child = spawn("ssh", args, {
33
+ stdio: ["ignore", "ignore", "pipe"],
34
+ });
35
+ let processExited = false;
36
+ const exitPromise = new Promise((resolve) => {
37
+ child.on("exit", () => {
38
+ processExited = true;
39
+ resolve();
40
+ });
41
+ });
42
+ const deadline = Date.now() + 10_000;
43
+ let ready = false;
44
+ while (Date.now() < deadline && !processExited) {
45
+ try {
46
+ await fs.stat(localSocket);
47
+ ready = true;
48
+ break;
49
+ }
50
+ catch {
51
+ await new Promise((r) => setTimeout(r, 100));
52
+ }
53
+ }
54
+ if (!ready) {
55
+ child.kill("SIGTERM");
56
+ let timerId;
57
+ const errText = await Promise.race([
58
+ drainStderr(child),
59
+ new Promise((r) => {
60
+ timerId = setTimeout(() => r(""), 5_000);
61
+ }),
62
+ ]);
63
+ clearTimeout(timerId);
64
+ await exitPromise;
65
+ await fs.rm(tempDir, { recursive: true, force: true }).catch(() => { });
66
+ throw new Error(`SSH tunnel to ${host} failed: ${errText.trim() || "socket not created within 10s"}`);
67
+ }
68
+ const inner = createTransport({
69
+ socketPath: localSocket,
70
+ apiVersion,
71
+ timeout,
72
+ auth,
73
+ });
74
+ return {
75
+ request: inner.request,
76
+ requestRaw: inner.requestRaw,
77
+ requestStream: inner.requestStream,
78
+ getAuthHeader: inner.getAuthHeader,
79
+ close() {
80
+ inner.close();
81
+ child.kill("SIGTERM");
82
+ fs.rm(tempDir, { recursive: true, force: true }).catch(() => { });
83
+ },
84
+ };
85
+ }
@@ -0,0 +1,23 @@
1
+ import { type AuthOption, type Transport } from "./transport_core.js";
2
+ export type { DoFetchFn, DoFetchInit, Transport, TransportResponse, } from "./transport_core.js";
3
+ export interface TransportOptions {
4
+ socketPath: string;
5
+ apiVersion?: string;
6
+ timeout?: number;
7
+ auth?: AuthOption;
8
+ }
9
+ export declare function createTransport(opts: TransportOptions): Transport;
10
+ export interface TlsOptions {
11
+ caCerts?: string[];
12
+ cert?: string;
13
+ key?: string;
14
+ }
15
+ export interface TcpTransportOptions {
16
+ uri: string;
17
+ apiVersion?: string;
18
+ timeout?: number;
19
+ auth?: AuthOption;
20
+ tls?: TlsOptions;
21
+ }
22
+ export declare function createTcpTransport(opts: TcpTransportOptions): Transport;
23
+ //# sourceMappingURL=transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,UAAU,EAGf,KAAK,SAAS,EACf,MAAM,qBAAqB,CAAC;AAE7B,YAAY,EACV,SAAS,EACT,WAAW,EACX,SAAS,EACT,iBAAiB,GAClB,MAAM,qBAAqB,CAAC;AA4E7B,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,gBAAgB,GAAG,SAAS,CAuBjE;AAID,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,GAAG,CAAC,EAAE,UAAU,CAAC;CAClB;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,mBAAmB,GAAG,SAAS,CAyCvE"}
@@ -0,0 +1,112 @@
1
+ import * as http from "node:http";
2
+ import * as https from "node:https";
3
+ import { buildTransport, } from "./transport_core.js";
4
+ // ─── Node http.request → web Response adapter ────────────────────────────────
5
+ function nodeRequest(url, options, body) {
6
+ return new Promise((resolve, reject) => {
7
+ const isHttps = url.startsWith("https:");
8
+ const requester = isHttps ? https.request : http.request;
9
+ const req = requester(url, options, (res) => {
10
+ const readable = new ReadableStream({
11
+ start(controller) {
12
+ res.on("data", (chunk) => controller.enqueue(new Uint8Array(chunk)));
13
+ res.on("end", () => controller.close());
14
+ res.on("error", (err) => controller.error(err));
15
+ },
16
+ cancel() {
17
+ res.destroy();
18
+ },
19
+ });
20
+ const headers = new Headers();
21
+ for (const [key, value] of Object.entries(res.headers)) {
22
+ if (value !== undefined) {
23
+ headers.set(key, Array.isArray(value) ? value.join(", ") : value);
24
+ }
25
+ }
26
+ resolve(new Response(readable, { status: res.statusCode ?? 0, headers }));
27
+ });
28
+ req.on("error", reject);
29
+ if (body !== undefined && body !== null) {
30
+ if (typeof body === "string") {
31
+ req.end(body);
32
+ return;
33
+ }
34
+ if (body instanceof ArrayBuffer) {
35
+ req.end(Buffer.from(body));
36
+ return;
37
+ }
38
+ if (body instanceof Uint8Array) {
39
+ req.end(Buffer.from(body.buffer, body.byteOffset, body.byteLength));
40
+ return;
41
+ }
42
+ if (body instanceof ReadableStream) {
43
+ const reader = body.getReader();
44
+ (function pump() {
45
+ reader.read().then(({ done, value }) => {
46
+ if (done) {
47
+ req.end();
48
+ return;
49
+ }
50
+ req.write(Buffer.from(value));
51
+ pump();
52
+ }).catch((err) => {
53
+ req.destroy(err);
54
+ reject(err);
55
+ });
56
+ })();
57
+ return;
58
+ }
59
+ }
60
+ req.end();
61
+ });
62
+ }
63
+ export function createTransport(opts) {
64
+ const { socketPath, apiVersion = "4.0.0", timeout = 30_000 } = opts;
65
+ const authHeader = opts.auth ? btoa(JSON.stringify(opts.auth)) : undefined;
66
+ const base = `/v${apiVersion}/libpod`;
67
+ const doFetch = async (method, path, init) => {
68
+ const signal = init?.signal !== undefined
69
+ ? (init.signal ?? undefined)
70
+ : AbortSignal.timeout(timeout);
71
+ return await nodeRequest(`http://localhost${base}${path}`, {
72
+ socketPath,
73
+ method,
74
+ headers: init?.headers,
75
+ signal: signal ?? undefined,
76
+ }, init?.body);
77
+ };
78
+ return buildTransport(doFetch, authHeader, () => { });
79
+ }
80
+ export function createTcpTransport(opts) {
81
+ const { uri, apiVersion = "4.0.0", timeout = 30_000 } = opts;
82
+ const authHeader = opts.auth ? btoa(JSON.stringify(opts.auth)) : undefined;
83
+ const base = `${uri.replace(/\/+$/, "")}/v${apiVersion}/libpod`;
84
+ let agent;
85
+ if (opts.tls) {
86
+ agent = new https.Agent({
87
+ ca: opts.tls.caCerts?.join("\n"),
88
+ cert: opts.tls.cert,
89
+ key: opts.tls.key,
90
+ });
91
+ }
92
+ const doFetch = async (method, path, init) => {
93
+ const signal = init?.signal !== undefined
94
+ ? (init.signal ?? undefined)
95
+ : AbortSignal.timeout(timeout);
96
+ if (agent) {
97
+ return await nodeRequest(`${base}${path}`, {
98
+ method,
99
+ headers: init?.headers,
100
+ agent,
101
+ signal: signal ?? undefined,
102
+ }, init?.body);
103
+ }
104
+ return await fetch(`${base}${path}`, {
105
+ method,
106
+ headers: init?.headers,
107
+ body: init?.body,
108
+ signal,
109
+ });
110
+ };
111
+ return buildTransport(doFetch, authHeader, () => agent?.destroy());
112
+ }