writetainer-lib 25.12.27-dev.9

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 (3) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +375 -0
  3. package/package.json +46 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025-2026 Erick Tran
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,375 @@
1
+ # Writetainer-Lib
2
+
3
+ A Portainer API accessibility library for Node.js, written in TypeScript. This library provides a convenient wrapper around the Portainer API, allowing you to easily interact with your Portainer instance to manage environments, stacks, and containers.
4
+
5
+ ## Features
6
+
7
+ - **Authentication**: Easy authentication using Portainer API tokens
8
+ - **Environment Management**: Fetch and manage Portainer environments (endpoints)
9
+ - **Stack Management**: Create, retrieve, start, stop, update, and delete stacks
10
+ - **Container Management**: Full container lifecycle management (start, stop, restart, remove, etc.)
11
+ - **Factory Pattern**: High-level factory methods for easy stack and container creation
12
+ - **TypeScript Support**: Fully typed interfaces for better development experience
13
+ - **Logging**: Built-in logging with debug package integration
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ npm install writetainer-lib
19
+ ```
20
+
21
+ ## Prerequisites
22
+
23
+ Create a `.env` file in your project root with the following variables:
24
+
25
+ ```env
26
+ PORTAINER_URL=https://your-portainer-instance.com
27
+ PORTAINER_API_KEY=your-api-token-here
28
+ ```
29
+
30
+ ## Quick Start
31
+
32
+ ### Basic Usage
33
+
34
+ ```typescript
35
+ import { PortainerApi, PortainerFactory, logInfo } from 'writetainer-lib';
36
+
37
+ // Get the singleton instance of PortainerApi
38
+ const api = PortainerApi.getInstance();
39
+
40
+ // Check connection status
41
+ const isConnected = await api.getStatus();
42
+ logInfo('Connected:', isConnected);
43
+
44
+ // Get all stacks
45
+ const stacks = await api.getStacks();
46
+ logInfo('Stacks:', stacks);
47
+
48
+ // Get all containers
49
+ const containers = await api.getContainers(true);
50
+ logInfo('Containers:', containers);
51
+ ```
52
+
53
+ ### Creating Stacks with Factory
54
+
55
+ ```typescript
56
+ import { PortainerFactory } from 'writetainer-lib';
57
+
58
+ const factory = PortainerFactory.getInstance();
59
+
60
+ const stackConfig = {
61
+ Name: "my-app-stack",
62
+ ComposeFile: `
63
+ services:
64
+ web:
65
+ image: nginx:latest
66
+ ports:
67
+ - "80:80"
68
+ restart: unless-stopped
69
+ `,
70
+ Env: [
71
+ { name: "ENVIRONMENT", value: "production" }
72
+ ]
73
+ };
74
+
75
+ // Create the stack
76
+ const stack = await factory.createStack(stackConfig);
77
+ ```
78
+
79
+ ### Container Management
80
+
81
+ ```typescript
82
+ import { PortainerApi } from 'writetainer-lib';
83
+
84
+ const api = PortainerApi.getInstance();
85
+
86
+ // Start a container
87
+ await api.handleContainer({
88
+ action: 'start',
89
+ containerId: 'container-id-here',
90
+ environmentId: 1
91
+ });
92
+
93
+ // Stop a container
94
+ await api.handleContainer({
95
+ action: 'stop',
96
+ containerId: 'container-id-here'
97
+ });
98
+
99
+ // Remove a container with options
100
+ await api.handleContainer({
101
+ action: 'remove',
102
+ containerId: 'container-id-here',
103
+ options: {
104
+ force: true,
105
+ removeVolumes: true
106
+ }
107
+ });
108
+
109
+ // Restart a container with custom timeout
110
+ await api.handleContainer({
111
+ action: 'restart',
112
+ containerId: 'container-id-here',
113
+ options: {
114
+ timeout: 30000 // 30 seconds
115
+ }
116
+ });
117
+ ```
118
+
119
+ ### Stack Operations
120
+
121
+ ```typescript
122
+ import { PortainerApi } from 'writetainer-lib';
123
+
124
+ const api = PortainerApi.getInstance();
125
+
126
+ // Start a stack
127
+ await api.startStack(stackId, environmentId);
128
+
129
+ // Stop a stack
130
+ await api.stopStack(stackId, environmentId);
131
+
132
+ // Update a stack with new compose content
133
+ await api.updateStack(stackId, newComposeContent, environmentId, true);
134
+
135
+ // Redeploy a stack (stop, pull, start)
136
+ await api.redeployStack(stackId, environmentId);
137
+
138
+ // Delete a stack
139
+ await api.deleteStack(stackId, environmentId);
140
+ ```
141
+
142
+ ### Environment Management
143
+
144
+ ```typescript
145
+ import { PortainerApi, getFirstEnvironmentId } from 'writetainer-lib';
146
+
147
+ const api = PortainerApi.getInstance();
148
+
149
+ // Get all environments
150
+ const environments = await api.getEnvironments();
151
+
152
+ // Get details of a specific environment
153
+ const envDetails = await api.getEnvironmentDetails(environmentId);
154
+
155
+ // Get first environment ID
156
+ const firstEnvId = await getFirstEnvironmentId();
157
+ ```
158
+
159
+ ### Resource Fetching
160
+
161
+ ```typescript
162
+ import { PortainerApi } from 'writetainer-lib';
163
+
164
+ const api = PortainerApi.getInstance();
165
+
166
+ // Get all containers (including stopped ones)
167
+ const allContainers = await api.getContainers(true);
168
+
169
+ // Get running containers only
170
+ const runningContainers = await api.getContainers(false);
171
+
172
+ // Get container details
173
+ const containerDetails = await api.getContainerDetails('container-id');
174
+
175
+ // Get container stats
176
+ const stats = await api.getContainerStats('container-id');
177
+
178
+ // Get images
179
+ const images = await api.getImages(environmentId);
180
+ ```
181
+
182
+ ### Utility Functions
183
+
184
+ ```typescript
185
+ import {
186
+ getStackByName,
187
+ getStackById,
188
+ getContainerByDetails,
189
+ verifyStackCreation,
190
+ verifyContainerCreation
191
+ } from 'writetainer-lib';
192
+
193
+ // Find a stack by name
194
+ const stack = await getStackByName('my-stack-name');
195
+
196
+ // Find a stack by ID
197
+ const stack = await getStackById(123, environmentId);
198
+
199
+ // Find container by image or label
200
+ const container = await getContainerByDetails({
201
+ image: 'nginx:latest'
202
+ });
203
+
204
+ // Verify stack creation
205
+ const isVerified = await verifyStackCreation('my-stack', 5000, 3);
206
+
207
+ // Verify container creation
208
+ const isRunning = await verifyContainerCreation('my-container', 5000);
209
+ ```
210
+
211
+ ## API Reference
212
+
213
+ ### Main Classes
214
+
215
+ #### `PortainerApi`
216
+ Singleton class that provides access to all Portainer API operations.
217
+
218
+ **Methods:**
219
+ - `getInstance(environmentId?: number | null)` - Get singleton instance
220
+ - `getEnvironments()` - Fetch all environments
221
+ - `getEnvironmentDetails(environmentId)` - Get environment details
222
+ - `getStacks()` - Get all stacks
223
+ - `getContainers(includeAll, environmentId?)` - Get containers
224
+ - `getContainerDetails(identifier, environmentId?)` - Get container details
225
+ - `getContainerStats(identifier, environmentId?)` - Get container stats
226
+ - `getImages(environmentId?)` - Get images
227
+ - `getStatus(environmentId?)` - Get system status
228
+ - `handleContainer(controls)` - Execute container actions
229
+ - `startStack(stackId, environmentId?)` - Start a stack
230
+ - `stopStack(stackId, environmentId?)` - Stop a stack
231
+ - `updateStack(stackId, composeContent, environmentId?, pullImage?)` - Update a stack
232
+ - `redeployStack(stackId, environmentId?)` - Redeploy a stack
233
+ - `deleteStack(stackId, environmentId?)` - Delete a stack
234
+ - `cleanupExistingContainer(containerName, environmentId?)` - Cleanup a container
235
+ - `ensureEnvId()` - Ensure environment ID is set
236
+
237
+ #### `PortainerFactory`
238
+ Singleton factory class for creating resources with validation.
239
+
240
+ **Methods:**
241
+ - `getInstance(environmentId?: number | null)` - Get singleton instance
242
+ - `createStack(stackData, maxRetryCount?, timeoutMs?)` - Create a new stack
243
+ - `createContainer(containerData, maxRetryCount?, timeoutMs?)` - Create a new container
244
+
245
+ #### `PortainerAuth`
246
+ Singleton class for authentication management.
247
+
248
+ **Properties:**
249
+ - `axiosInstance` - Configured axios instance
250
+ - `isValidated` - Authentication validation status
251
+ - `PortainerUrl` - Portainer URL
252
+
253
+ **Methods:**
254
+ - `getInstance()` - Get singleton instance
255
+
256
+ ### Type Definitions
257
+
258
+ ```typescript
259
+ interface PortainerEnvironment {
260
+ Id: number;
261
+ Name: string;
262
+ }
263
+
264
+ interface PortainerStack {
265
+ Id: number;
266
+ Name: string;
267
+ EndpointId: number;
268
+ }
269
+
270
+ interface PortainerContainer {
271
+ Id: string;
272
+ Names: string[];
273
+ Image: string;
274
+ Labels: { [key: string]: string };
275
+ State: string;
276
+ Status: string;
277
+ // ... additional properties
278
+ }
279
+
280
+ interface PortainerImage {
281
+ Id: string;
282
+ RepoTags: string[];
283
+ Created: number;
284
+ Size: number;
285
+ }
286
+
287
+ interface PortainerStackContent {
288
+ Name: string;
289
+ ComposeFile: string | any;
290
+ Env?: Array<{ name: string; value: string }>;
291
+ FromAppTemplate?: boolean;
292
+ }
293
+ ```
294
+
295
+ ## Logging
296
+
297
+ The library uses the `debug` package for logging. To enable logs:
298
+
299
+ ```bash
300
+ # Enable all logs
301
+ DEBUG=portainer-api:* node your-app.js
302
+
303
+ # Enable only info logs
304
+ DEBUG=portainer-api:info node your-app.js
305
+
306
+ # Enable error and warning logs
307
+ DEBUG=portainer-api:error,portainer-api:warn node your-app.js
308
+ ```
309
+
310
+ You can also use the built-in logging functions:
311
+
312
+ ```typescript
313
+ import { logInfo, logWarn, logError } from 'writetainer-lib';
314
+
315
+ logInfo('This is an info message');
316
+ logWarn('This is a warning');
317
+ logError('This is an error', errorObject);
318
+ ```
319
+
320
+ #### Get Stacks
321
+
322
+ ```typescript
323
+ const stacks = await client.getStacks();
324
+ console.log(stacks);
325
+ ```
326
+
327
+ #### Get Containers
328
+
329
+ Fetch all containers (running and stopped) for the default environment.
330
+
331
+ ```typescript
332
+ const containers = await client.getContainers(true);
333
+ console.log(containers);
334
+ ```
335
+
336
+ #### Test Connection
337
+
338
+ ```typescript
339
+ const isConnected = await client.testConnection();
340
+ if (isConnected) {
341
+ console.log('Connected to Portainer!');
342
+ }
343
+ ```
344
+
345
+ ## API Reference
346
+
347
+ ### `PortainerApiClient`
348
+
349
+ #### Constructor
350
+ `new PortainerApiClient(portainerUrl: string, apiToken: string, environmentId?: number | null)`
351
+
352
+ #### Methods
353
+
354
+ - `getEnvironments(): Promise<PortainerEnvironment[]>`
355
+ - Fetches a list of all Portainer environments.
356
+
357
+ - `getEnvironment(environmentId: number): Promise<PortainerEnvironment>`
358
+ - Fetches details of a specific environment.
359
+
360
+ - `getStacks(): Promise<PortainerStack[]>`
361
+ - Fetches a list of all stacks.
362
+
363
+ - `getContainers(includeAll: boolean): Promise<PortainerContainer[] | undefined>`
364
+ - Fetches a list of containers for the current environment.
365
+ - `includeAll`: Set to `true` to include stopped containers.
366
+
367
+ - `testConnection(): Promise<boolean>`
368
+ - Tests the connection to the Portainer API.
369
+
370
+ - `DefaultEnvironmentId` (Getter/Setter)
371
+ - Get or set the default environment ID used for container operations.
372
+
373
+ ## License
374
+
375
+ MIT
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "writetainer-lib",
3
+ "version": "25.12.27-dev.9",
4
+ "description": "A TypeScript library for interacting with the Portainer API to manage Docker containers and stacks programmatically.",
5
+ "homepage": "https://github.com/enVId-tech/Writetainer-Lib#readme",
6
+ "bugs": {
7
+ "url": "https://github.com/enVId-tech/Writetainer-Lib/issues"
8
+ },
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/enVId-tech/Writetainer-Lib.git"
12
+ },
13
+ "license": "MIT",
14
+ "author": "envid-tech",
15
+ "scripts": {
16
+ "test": "vitest",
17
+ "build": "tsc",
18
+ "ncu": "npx npm-check-updates -u && npm install"
19
+ },
20
+ "dependencies": {
21
+ "axios": "^1.13.6",
22
+ "debug": "^4.4.3",
23
+ "dotenv": "^17.3.1",
24
+ "typescript": "^5.9.3"
25
+ },
26
+ "main": "./dist/index.js",
27
+ "types": "./dist/index.d.ts",
28
+ "exports": {
29
+ ".": {
30
+ "types": "./dist/index.d.ts",
31
+ "import": "./dist/index.js"
32
+ }
33
+ },
34
+ "files": [
35
+ "dist",
36
+ "README.md",
37
+ "LICENSE"
38
+ ],
39
+ "devDependencies": {
40
+ "@testing-library/jest-dom": "^6.9.1",
41
+ "@types/debug": "^4.1.13",
42
+ "@types/node": "^25.5.0",
43
+ "vitest": "^4.1.0"
44
+ },
45
+ "type": "module"
46
+ }