Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 889b017d4f | |||
| 35e8eff092 | |||
| 2ecd4e9d7c | |||
| 08dbad47bc | |||
| 15e5dedae4 | |||
| 5834721da8 | |||
| 2f31e14cbe | |||
| 5691e5fb78 |
73
changelog.md
73
changelog.md
@@ -1,5 +1,76 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 2025-11-24 - 5.0.2 - fix(DockerContainer)
|
||||||
|
Fix getContainerById to return undefined for non-existent containers
|
||||||
|
|
||||||
|
- Prevented creation of an invalid DockerContainer from Docker API error responses when a container does not exist.
|
||||||
|
- Changed DockerContainer._fromId to use the list+find pattern and return Promise<DockerContainer | undefined>.
|
||||||
|
- Updated DockerHost.getContainerById to return Promise<DockerContainer | undefined> for type safety and consistent behavior.
|
||||||
|
- Added tests to verify undefined is returned for non-existent container IDs and that valid IDs return DockerContainer instances.
|
||||||
|
- Bumped package version to 5.0.1 and updated changelog and readme hints to document the fix.
|
||||||
|
|
||||||
|
## 2025-11-24 - 5.0.0 - BREAKING CHANGE(DockerHost)
|
||||||
|
Rename array-returning get* methods to list* on DockerHost and related resource classes; update docs, tests and changelog
|
||||||
|
|
||||||
|
- Renamed public DockerHost methods: getContainers → listContainers, getNetworks → listNetworks, getServices → listServices, getImages → listImages, getSecrets → listSecrets.
|
||||||
|
- Renamed DockerNetwork.getContainersOnNetwork → DockerNetwork.listContainersOnNetwork and updated usages (e.g. getContainersOnNetworkForService).
|
||||||
|
- Updated internal/static method docs/comments to recommend dockerHost.list*() usage and adjusted implementations accordingly.
|
||||||
|
- Updated README, readme.hints.md, tests (test.nonci.node+deno.ts) and changelog to reflect the new list* method names.
|
||||||
|
- Bumped package version to 4.0.0.
|
||||||
|
- Migration note: replace calls to get*() with list*() for methods that return multiple items (arrays). Single-item getters such as getContainerById or getNetworkByName remain unchanged.
|
||||||
|
|
||||||
|
## 2025-11-24 - 5.0.1 - fix(DockerContainer)
|
||||||
|
Fix getContainerById() to return undefined instead of invalid container object when container doesn't exist
|
||||||
|
|
||||||
|
**Bug Fixed:**
|
||||||
|
- `getContainerById()` was creating a DockerContainer object from error responses when a container didn't exist
|
||||||
|
- The error object `{ message: "No such container: ..." }` was being passed to the constructor
|
||||||
|
- Calling `.logs()` on this invalid container returned "[object Object]" instead of logs
|
||||||
|
|
||||||
|
**Solution:**
|
||||||
|
- Changed `DockerContainer._fromId()` to use the list+filter pattern (consistent with all other resource getters)
|
||||||
|
- Now returns `undefined` when container is not found (matches DockerImage, DockerNetwork, DockerService, DockerSecret behavior)
|
||||||
|
- Updated return type to `Promise<DockerContainer | undefined>` for type safety
|
||||||
|
- Added tests to verify undefined is returned for non-existent containers
|
||||||
|
|
||||||
|
**Migration:**
|
||||||
|
No breaking changes - users should already be checking for undefined/null based on TypeScript types and documentation.
|
||||||
|
|
||||||
|
## 2025-11-24 - 4.0.0 - BREAKING CHANGE: Rename list methods for consistency
|
||||||
|
|
||||||
|
**Breaking Changes:**
|
||||||
|
- Renamed all "get*" methods that return arrays to "list*" methods for better clarity:
|
||||||
|
- `getContainers()` → `listContainers()`
|
||||||
|
- `getNetworks()` → `listNetworks()`
|
||||||
|
- `getServices()` → `listServices()`
|
||||||
|
- `getImages()` → `listImages()`
|
||||||
|
- `getSecrets()` → `listSecrets()`
|
||||||
|
- `getContainersOnNetwork()` → `listContainersOnNetwork()` (on DockerNetwork class)
|
||||||
|
|
||||||
|
**Migration Guide:**
|
||||||
|
Update all method calls from `get*()` to `list*()` where the method returns an array of resources. Single-item getters like `getContainerById()`, `getNetworkByName()`, etc. remain unchanged.
|
||||||
|
|
||||||
|
**Rationale:**
|
||||||
|
The `list*` naming convention more clearly indicates that these methods return multiple items (arrays), while `get*` methods are reserved for retrieving single items by ID or name. This follows standard API design patterns and improves code readability.
|
||||||
|
|
||||||
|
## 2025-11-24 - 3.0.2 - fix(readme)
|
||||||
|
Update README to document 3.0.0+ changes: architecture refactor, streaming improvements, health check and circular dependency fixes
|
||||||
|
|
||||||
|
- Documented major refactor to a Clean OOP / Facade pattern with DockerHost as the single entry point
|
||||||
|
- Added/clarified real-time container streaming APIs: streamLogs(), attach(), exec()
|
||||||
|
- Clarified support for flexible descriptors (accept both string references and class instances)
|
||||||
|
- Documented complete container lifecycle API (start, stop, remove, logs, inspect, stats)
|
||||||
|
- Documented new ping() health check method to verify Docker daemon availability
|
||||||
|
- Noted fix for circular dependency issues in Node.js by using type-only imports
|
||||||
|
- Mentioned improved TypeScript definitions and expanded examples, migration guides, and real-world use cases
|
||||||
|
|
||||||
|
## 2025-11-24 - 3.0.1 - fix(classes.base)
|
||||||
|
Use type-only import for DockerHost in classes.base to avoid runtime side-effects
|
||||||
|
|
||||||
|
- Changed the import in ts/classes.base.ts to a type-only import: import type { DockerHost } from './classes.host.js';
|
||||||
|
- Prevents a runtime import of classes.host when only the type is needed, reducing risk of circular dependencies and unintended side-effects during module initialization.
|
||||||
|
- No behavior changes to the public API — TypeScript-only change; intended to improve bundling and runtime stability.
|
||||||
|
|
||||||
## 2025-11-24 - 3.0.0 - BREAKING CHANGE(DockerHost)
|
## 2025-11-24 - 3.0.0 - BREAKING CHANGE(DockerHost)
|
||||||
Refactor public API to DockerHost facade; introduce DockerResource base; make resource static methods internal; support flexible descriptors and stream compatibility
|
Refactor public API to DockerHost facade; introduce DockerResource base; make resource static methods internal; support flexible descriptors and stream compatibility
|
||||||
|
|
||||||
@@ -11,7 +82,7 @@ Refactor public API to DockerHost facade; introduce DockerResource base; make re
|
|||||||
- Streaming compatibility: updated requestStreaming to convert web ReadableStreams (smartrequest v5+) to Node.js streams via smartstream.nodewebhelpers, preserving backward compatibility for existing streaming APIs (container logs, attach, exec, image import/export, events).
|
- Streaming compatibility: updated requestStreaming to convert web ReadableStreams (smartrequest v5+) to Node.js streams via smartstream.nodewebhelpers, preserving backward compatibility for existing streaming APIs (container logs, attach, exec, image import/export, events).
|
||||||
- Container enhancements: added full lifecycle and streaming/interactive APIs on DockerContainer: refresh(), inspect(), start(), stop(), remove(), logs(), stats(), streamLogs(), attach(), exec().
|
- Container enhancements: added full lifecycle and streaming/interactive APIs on DockerContainer: refresh(), inspect(), start(), stop(), remove(), logs(), stats(), streamLogs(), attach(), exec().
|
||||||
- Service creation updated: resolves image/network/secret descriptors (strings or instances); adds labels.version from image; improved resource handling and port/secret/network resolution.
|
- Service creation updated: resolves image/network/secret descriptors (strings or instances); adds labels.version from image; improved resource handling and port/secret/network resolution.
|
||||||
- Network and Secret classes updated to extend DockerResource and to expose refresh(), remove() and lookup methods via DockerHost (createNetwork/getNetworks/getNetworkByName, createSecret/getSecrets/getSecretByName/getSecretById).
|
- Network and Secret classes updated to extend DockerResource and to expose refresh(), remove() and lookup methods via DockerHost (createNetwork/listNetworks/getNetworkByName, createSecret/listSecrets/getSecretByName/getSecretById).
|
||||||
- Tests and docs updated: migration guide and examples added (readme.hints.md, README); test timeout reduced from 600s to 300s in package.json.
|
- Tests and docs updated: migration guide and examples added (readme.hints.md, README); test timeout reduced from 600s to 300s in package.json.
|
||||||
- BREAKING: Public API changes require consumers to migrate away from direct resource static calls and direct imageStore access to the new DockerHost-based factory methods and storeImage/retrieveImage APIs.
|
- BREAKING: Public API changes require consumers to migrate away from direct resource static calls and direct imageStore access to the new DockerHost-based factory methods and storeImage/retrieveImage APIs.
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@apiclient.xyz/docker",
|
"name": "@apiclient.xyz/docker",
|
||||||
"version": "3.0.0",
|
"version": "5.0.2",
|
||||||
"description": "Provides easy communication with Docker remote API from Node.js, with TypeScript support.",
|
"description": "Provides easy communication with Docker remote API from Node.js, with TypeScript support.",
|
||||||
"private": false,
|
"private": false,
|
||||||
"main": "dist_ts/index.js",
|
"main": "dist_ts/index.js",
|
||||||
|
|||||||
@@ -1,5 +1,52 @@
|
|||||||
# Docker Module - Development Hints
|
# Docker Module - Development Hints
|
||||||
|
|
||||||
|
## getContainerById() Bug Fix (2025-11-24 - v5.0.1)
|
||||||
|
|
||||||
|
### Problem
|
||||||
|
The `getContainerById()` method had a critical bug where it would create a DockerContainer object from Docker API error responses when a container didn't exist.
|
||||||
|
|
||||||
|
**Symptoms:**
|
||||||
|
- Calling `docker.getContainerById('invalid-id')` returned a DockerContainer object with `{ message: "No such container: invalid-id" }`
|
||||||
|
- Calling `.logs()` on this invalid container returned "[object Object]" instead of logs or throwing an error
|
||||||
|
- No way to detect the error state without checking for a `.message` property
|
||||||
|
|
||||||
|
**Root Cause:**
|
||||||
|
The `DockerContainer._fromId()` method made a direct API call to `/containers/{id}/json` and blindly passed `response.body` to the constructor, even when the API returned a 404 error response.
|
||||||
|
|
||||||
|
### Solution
|
||||||
|
Changed `DockerContainer._fromId()` to use the **list+filter pattern**, matching the behavior of all other resource getter methods (DockerImage, DockerNetwork, DockerService, DockerSecret):
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Before (buggy):
|
||||||
|
public static async _fromId(dockerHostArg: DockerHost, containerId: string): Promise<DockerContainer> {
|
||||||
|
const response = await dockerHostArg.request('GET', `/containers/${containerId}/json`);
|
||||||
|
return new DockerContainer(dockerHostArg, response.body); // Creates invalid object from error!
|
||||||
|
}
|
||||||
|
|
||||||
|
// After (fixed):
|
||||||
|
public static async _fromId(dockerHostArg: DockerHost, containerId: string): Promise<DockerContainer | undefined> {
|
||||||
|
const containers = await this._list(dockerHostArg);
|
||||||
|
return containers.find((container) => container.Id === containerId); // Returns undefined if not found
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Benefits:**
|
||||||
|
- 100% consistent with all other resource classes
|
||||||
|
- Type-safe return signature: `Promise<DockerContainer | undefined>`
|
||||||
|
- Cannot create invalid objects - `.find()` naturally returns undefined
|
||||||
|
- Users can now properly check for non-existent containers
|
||||||
|
|
||||||
|
**Usage:**
|
||||||
|
```typescript
|
||||||
|
const container = await docker.getContainerById('abc123');
|
||||||
|
if (container) {
|
||||||
|
const logs = await container.logs();
|
||||||
|
console.log(logs);
|
||||||
|
} else {
|
||||||
|
console.log('Container not found');
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## OOP Refactoring - Clean Architecture (2025-11-24)
|
## OOP Refactoring - Clean Architecture (2025-11-24)
|
||||||
|
|
||||||
### Architecture Changes
|
### Architecture Changes
|
||||||
@@ -19,7 +66,7 @@ The module has been restructured to follow a clean OOP Facade pattern:
|
|||||||
const network = await DockerNetwork.createNetwork(dockerHost, descriptor);
|
const network = await DockerNetwork.createNetwork(dockerHost, descriptor);
|
||||||
|
|
||||||
// New (clean API):
|
// New (clean API):
|
||||||
const containers = await dockerHost.getContainers();
|
const containers = await dockerHost.listContainers();
|
||||||
const network = await dockerHost.createNetwork(descriptor);
|
const network = await dockerHost.createNetwork(descriptor);
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -113,7 +160,7 @@ await dockerHost.createService({
|
|||||||
|
|
||||||
### Migration Guide
|
### Migration Guide
|
||||||
Replace all static method calls with dockerHost methods:
|
Replace all static method calls with dockerHost methods:
|
||||||
- `DockerContainer.getContainers(host)` → `dockerHost.getContainers()`
|
- `DockerContainer.getContainers(host)` → `dockerHost.listContainers()`
|
||||||
- `DockerImage.createFromRegistry(host, opts)` → `dockerHost.createImageFromRegistry(opts)`
|
- `DockerImage.createFromRegistry(host, opts)` → `dockerHost.createImageFromRegistry(opts)`
|
||||||
- `DockerService.createService(host, desc)` → `dockerHost.createService(desc)`
|
- `DockerService.createService(host, desc)` → `dockerHost.createService(desc)`
|
||||||
- `dockerHost.imageStore.storeImage(...)` → `dockerHost.storeImage(...)`
|
- `dockerHost.imageStore.storeImage(...)` → `dockerHost.storeImage(...)`
|
||||||
|
|||||||
34
readme.md
34
readme.md
@@ -48,7 +48,7 @@ await docker.ping();
|
|||||||
console.log('✅ Docker is running');
|
console.log('✅ Docker is running');
|
||||||
|
|
||||||
// List all containers
|
// List all containers
|
||||||
const containers = await docker.getContainers();
|
const containers = await docker.listContainers();
|
||||||
console.log(`Found ${containers.length} containers`);
|
console.log(`Found ${containers.length} containers`);
|
||||||
|
|
||||||
// Get a specific container and interact with it
|
// Get a specific container and interact with it
|
||||||
@@ -71,7 +71,7 @@ The module follows a **Facade pattern** with `DockerHost` as the single entry po
|
|||||||
const docker = new DockerHost({});
|
const docker = new DockerHost({});
|
||||||
|
|
||||||
// All operations go through DockerHost
|
// All operations go through DockerHost
|
||||||
const containers = await docker.getContainers(); // List containers
|
const containers = await docker.listContainers(); // List containers
|
||||||
const container = await docker.getContainerById('id'); // Get specific container
|
const container = await docker.getContainerById('id'); // Get specific container
|
||||||
const network = await docker.createNetwork({ Name: 'my-net' }); // Create network
|
const network = await docker.createNetwork({ Name: 'my-net' }); // Create network
|
||||||
const service = await docker.createService(descriptor); // Deploy service
|
const service = await docker.createService(descriptor); // Deploy service
|
||||||
@@ -181,7 +181,7 @@ async function waitForDocker(timeoutMs = 10000): Promise<void> {
|
|||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
// Get all containers (running and stopped)
|
// Get all containers (running and stopped)
|
||||||
const containers = await docker.getContainers();
|
const containers = await docker.listContainers();
|
||||||
|
|
||||||
containers.forEach((container) => {
|
containers.forEach((container) => {
|
||||||
console.log(`Container: ${container.Names[0]}`);
|
console.log(`Container: ${container.Names[0]}`);
|
||||||
@@ -406,7 +406,7 @@ writeStream.on('finish', () => {
|
|||||||
#### List All Images
|
#### List All Images
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
const images = await docker.getImages();
|
const images = await docker.listImages();
|
||||||
|
|
||||||
images.forEach((img) => {
|
images.forEach((img) => {
|
||||||
console.log(`Image: ${img.RepoTags ? img.RepoTags.join(', ') : '<none>'}`);
|
console.log(`Image: ${img.RepoTags ? img.RepoTags.join(', ') : '<none>'}`);
|
||||||
@@ -444,7 +444,7 @@ console.log(`Network created: ${network.Name} (${network.Id})`);
|
|||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
// Get all networks
|
// Get all networks
|
||||||
const networks = await docker.getNetworks();
|
const networks = await docker.listNetworks();
|
||||||
|
|
||||||
networks.forEach((net) => {
|
networks.forEach((net) => {
|
||||||
console.log(`Network: ${net.Name} (${net.Driver})`);
|
console.log(`Network: ${net.Name} (${net.Driver})`);
|
||||||
@@ -456,7 +456,7 @@ networks.forEach((net) => {
|
|||||||
const appNetwork = await docker.getNetworkByName('my-app-network');
|
const appNetwork = await docker.getNetworkByName('my-app-network');
|
||||||
|
|
||||||
// Get containers connected to this network
|
// Get containers connected to this network
|
||||||
const containers = await appNetwork.getContainersOnNetwork();
|
const containers = await appNetwork.listContainersOnNetwork();
|
||||||
console.log(`Containers on network: ${containers.length}`);
|
console.log(`Containers on network: ${containers.length}`);
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -523,7 +523,7 @@ console.log(`Service deployed: ${service.ID}`);
|
|||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
// List all services
|
// List all services
|
||||||
const services = await docker.getServices();
|
const services = await docker.listServices();
|
||||||
|
|
||||||
services.forEach((service) => {
|
services.forEach((service) => {
|
||||||
console.log(`Service: ${service.Spec.Name}`);
|
console.log(`Service: ${service.Spec.Name}`);
|
||||||
@@ -566,7 +566,7 @@ const secret = await docker.createSecret({
|
|||||||
console.log(`Secret created: ${secret.ID}`);
|
console.log(`Secret created: ${secret.ID}`);
|
||||||
|
|
||||||
// List all secrets
|
// List all secrets
|
||||||
const secrets = await docker.getSecrets();
|
const secrets = await docker.listSecrets();
|
||||||
secrets.forEach((s) => {
|
secrets.forEach((s) => {
|
||||||
console.log(`Secret: ${s.Spec.Name}`);
|
console.log(`Secret: ${s.Spec.Name}`);
|
||||||
console.log(` Labels:`, s.Spec.Labels);
|
console.log(` Labels:`, s.Spec.Labels);
|
||||||
@@ -868,7 +868,7 @@ async function healthCheckService() {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
await docker.ping();
|
await docker.ping();
|
||||||
const containers = await docker.getContainers();
|
const containers = await docker.listContainers();
|
||||||
|
|
||||||
const unhealthy = containers.filter(c => c.State !== 'running');
|
const unhealthy = containers.filter(c => c.State !== 'running');
|
||||||
if (unhealthy.length > 0) {
|
if (unhealthy.length > 0) {
|
||||||
@@ -904,15 +904,17 @@ async function healthCheckService() {
|
|||||||
|
|
||||||
## 🆕 Recent Updates
|
## 🆕 Recent Updates
|
||||||
|
|
||||||
### Version 2.1.0 - Architecture & Features
|
### Version 3.0.0+ - Architecture & Stability
|
||||||
|
|
||||||
- ✨ **Clean OOP Architecture**: Refactored to Facade pattern with DockerHost as single entry point
|
- ✨ **Clean OOP Architecture**: Refactored to Facade pattern with DockerHost as single entry point
|
||||||
- ✨ **Container Streaming**: Added `streamLogs()`, `attach()`, and `exec()` methods
|
- ✨ **Container Streaming**: Real-time `streamLogs()`, `attach()`, and `exec()` methods for interactive containers
|
||||||
- ✨ **Flexible Descriptors**: Support both string references and class instances
|
- ✨ **Flexible Descriptors**: Support both string references and class instances in all creation methods
|
||||||
- ✨ **Complete Container API**: All lifecycle methods (start, stop, remove, logs, inspect, stats)
|
- ✨ **Complete Container API**: Full lifecycle methods (start, stop, remove, logs, inspect, stats)
|
||||||
- ✨ **DockerResource Base Class**: Consistent patterns across all resources
|
- ✨ **DockerResource Base Class**: Consistent patterns and type safety across all resources
|
||||||
- 🔧 **Improved Type Safety**: Better TypeScript definitions throughout
|
- ✨ **Health Check Support**: New `ping()` method to verify Docker daemon availability
|
||||||
- 📚 **Enhanced Documentation**: Comprehensive examples and migration guides
|
- 🐛 **Fixed Circular Dependencies**: Resolved Node.js module loading issues with type-only imports
|
||||||
|
- 🔧 **Improved Type Safety**: Better TypeScript definitions and interfaces throughout
|
||||||
|
- 📚 **Enhanced Documentation**: Comprehensive examples, migration guides, and real-world use cases
|
||||||
|
|
||||||
## License and Legal Information
|
## License and Legal Information
|
||||||
|
|
||||||
|
|||||||
@@ -22,13 +22,13 @@ tap.test('should create a docker swarm', async () => {
|
|||||||
|
|
||||||
// Containers
|
// Containers
|
||||||
tap.test('should list containers', async () => {
|
tap.test('should list containers', async () => {
|
||||||
const containers = await testDockerHost.getContainers();
|
const containers = await testDockerHost.listContainers();
|
||||||
console.log(containers);
|
console.log(containers);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Networks
|
// Networks
|
||||||
tap.test('should list networks', async () => {
|
tap.test('should list networks', async () => {
|
||||||
const networks = await testDockerHost.getNetworks();
|
const networks = await testDockerHost.listNetworks();
|
||||||
console.log(networks);
|
console.log(networks);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -86,7 +86,7 @@ tap.test('should activate swarm mode', async () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
tap.test('should list all services', async (tools) => {
|
tap.test('should list all services', async (tools) => {
|
||||||
const services = await testDockerHost.getServices();
|
const services = await testDockerHost.listServices();
|
||||||
console.log(services);
|
console.log(services);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -165,11 +165,27 @@ tap.test('should expose a working DockerImageStore', async () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// CONTAINER GETTERS
|
||||||
|
tap.test('should return undefined for non-existent container', async () => {
|
||||||
|
const container = await testDockerHost.getContainerById('invalid-container-id-12345');
|
||||||
|
expect(container).toEqual(undefined);
|
||||||
|
});
|
||||||
|
|
||||||
|
tap.test('should return container for valid container ID', async () => {
|
||||||
|
const containers = await testDockerHost.listContainers();
|
||||||
|
if (containers.length > 0) {
|
||||||
|
const validId = containers[0].Id;
|
||||||
|
const container = await testDockerHost.getContainerById(validId);
|
||||||
|
expect(container).toBeInstanceOf(docker.DockerContainer);
|
||||||
|
expect(container?.Id).toEqual(validId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// CONTAINER STREAMING FEATURES
|
// CONTAINER STREAMING FEATURES
|
||||||
let testContainer: docker.DockerContainer;
|
let testContainer: docker.DockerContainer;
|
||||||
|
|
||||||
tap.test('should get an existing container for streaming tests', async () => {
|
tap.test('should get an existing container for streaming tests', async () => {
|
||||||
const containers = await testDockerHost.getContainers();
|
const containers = await testDockerHost.listContainers();
|
||||||
|
|
||||||
// Use the first running container we find
|
// Use the first running container we find
|
||||||
testContainer = containers.find((c) => c.State === 'running');
|
testContainer = containers.find((c) => c.State === 'running');
|
||||||
|
|||||||
@@ -3,6 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
export const commitinfo = {
|
export const commitinfo = {
|
||||||
name: '@apiclient.xyz/docker',
|
name: '@apiclient.xyz/docker',
|
||||||
version: '3.0.0',
|
version: '5.0.2',
|
||||||
description: 'Provides easy communication with Docker remote API from Node.js, with TypeScript support.'
|
description: 'Provides easy communication with Docker remote API from Node.js, with TypeScript support.'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { DockerHost } from './classes.host.js';
|
import type { DockerHost } from './classes.host.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract base class for all Docker resources.
|
* Abstract base class for all Docker resources.
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ export class DockerContainer extends DockerResource {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal: Get all containers
|
* Internal: Get all containers
|
||||||
* Public API: Use dockerHost.getContainers() instead
|
* Public API: Use dockerHost.listContainers() instead
|
||||||
*/
|
*/
|
||||||
public static async _list(
|
public static async _list(
|
||||||
dockerHostArg: DockerHost,
|
dockerHostArg: DockerHost,
|
||||||
@@ -28,13 +28,14 @@ export class DockerContainer extends DockerResource {
|
|||||||
/**
|
/**
|
||||||
* Internal: Get a container by ID
|
* Internal: Get a container by ID
|
||||||
* Public API: Use dockerHost.getContainerById(id) instead
|
* Public API: Use dockerHost.getContainerById(id) instead
|
||||||
|
* Returns undefined if container does not exist
|
||||||
*/
|
*/
|
||||||
public static async _fromId(
|
public static async _fromId(
|
||||||
dockerHostArg: DockerHost,
|
dockerHostArg: DockerHost,
|
||||||
containerId: string,
|
containerId: string,
|
||||||
): Promise<DockerContainer> {
|
): Promise<DockerContainer | undefined> {
|
||||||
const response = await dockerHostArg.request('GET', `/containers/${containerId}/json`);
|
const containers = await this._list(dockerHostArg);
|
||||||
return new DockerContainer(dockerHostArg, response.body);
|
return containers.find((container) => container.Id === containerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -129,9 +129,9 @@ export class DockerHost {
|
|||||||
// ==============
|
// ==============
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets all networks
|
* Lists all networks
|
||||||
*/
|
*/
|
||||||
public async getNetworks() {
|
public async listNetworks() {
|
||||||
return await DockerNetwork._list(this);
|
return await DockerNetwork._list(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,16 +156,17 @@ export class DockerHost {
|
|||||||
// ==============
|
// ==============
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets all containers
|
* Lists all containers
|
||||||
*/
|
*/
|
||||||
public async getContainers() {
|
public async listContainers() {
|
||||||
return await DockerContainer._list(this);
|
return await DockerContainer._list(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a container by ID
|
* Gets a container by ID
|
||||||
|
* Returns undefined if container does not exist
|
||||||
*/
|
*/
|
||||||
public async getContainerById(containerId: string) {
|
public async getContainerById(containerId: string): Promise<DockerContainer | undefined> {
|
||||||
return await DockerContainer._fromId(this, containerId);
|
return await DockerContainer._fromId(this, containerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,9 +184,9 @@ export class DockerHost {
|
|||||||
// ==============
|
// ==============
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets all services
|
* Lists all services
|
||||||
*/
|
*/
|
||||||
public async getServices() {
|
public async listServices() {
|
||||||
return await DockerService._list(this);
|
return await DockerService._list(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -210,9 +211,9 @@ export class DockerHost {
|
|||||||
// ==============
|
// ==============
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets all images
|
* Lists all images
|
||||||
*/
|
*/
|
||||||
public async getImages() {
|
public async listImages() {
|
||||||
return await DockerImage._list(this);
|
return await DockerImage._list(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -259,9 +260,9 @@ export class DockerHost {
|
|||||||
// ==============
|
// ==============
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets all secrets
|
* Lists all secrets
|
||||||
*/
|
*/
|
||||||
public async getSecrets() {
|
public async listSecrets() {
|
||||||
return await DockerSecret._list(this);
|
return await DockerSecret._list(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ export class DockerImage extends DockerResource {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal: Get all images
|
* Internal: Get all images
|
||||||
* Public API: Use dockerHost.getImages() instead
|
* Public API: Use dockerHost.listImages() instead
|
||||||
*/
|
*/
|
||||||
public static async _list(dockerHost: DockerHost) {
|
public static async _list(dockerHost: DockerHost) {
|
||||||
const images: DockerImage[] = [];
|
const images: DockerImage[] = [];
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ export class DockerNetwork extends DockerResource {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getContainersOnNetwork(): Promise<
|
public async listContainersOnNetwork(): Promise<
|
||||||
Array<{
|
Array<{
|
||||||
Name: string;
|
Name: string;
|
||||||
EndpointID: string;
|
EndpointID: string;
|
||||||
@@ -151,7 +151,7 @@ export class DockerNetwork extends DockerResource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async getContainersOnNetworkForService(serviceArg: DockerService) {
|
public async getContainersOnNetworkForService(serviceArg: DockerService) {
|
||||||
const containersOnNetwork = await this.getContainersOnNetwork();
|
const containersOnNetwork = await this.listContainersOnNetwork();
|
||||||
const containersOfService = containersOnNetwork.filter((container) => {
|
const containersOfService = containersOnNetwork.filter((container) => {
|
||||||
return container.Name.startsWith(serviceArg.Spec.Name);
|
return container.Name.startsWith(serviceArg.Spec.Name);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ export class DockerSecret extends DockerResource {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal: Get all secrets
|
* Internal: Get all secrets
|
||||||
* Public API: Use dockerHost.getSecrets() instead
|
* Public API: Use dockerHost.listSecrets() instead
|
||||||
*/
|
*/
|
||||||
public static async _list(dockerHostArg: DockerHost) {
|
public static async _list(dockerHostArg: DockerHost) {
|
||||||
const response = await dockerHostArg.request('GET', '/secrets');
|
const response = await dockerHostArg.request('GET', '/secrets');
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ export class DockerService extends DockerResource {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal: Get all services
|
* Internal: Get all services
|
||||||
* Public API: Use dockerHost.getServices() instead
|
* Public API: Use dockerHost.listServices() instead
|
||||||
*/
|
*/
|
||||||
public static async _list(dockerHost: DockerHost) {
|
public static async _list(dockerHost: DockerHost) {
|
||||||
const services: DockerService[] = [];
|
const services: DockerService[] = [];
|
||||||
|
|||||||
Reference in New Issue
Block a user