@tryhuset/foundation-utils 4.85.0 → 4.85.1

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 CHANGED
@@ -53,13 +53,33 @@ foundation-utils docker update --no-backup
53
53
  foundation-utils docker backup --restore ./docker_image_backups/docker-compose_20260101T120000.yaml --force
54
54
  foundation-utils docker update --force
55
55
 
56
- # Restart a specific service
56
+ # Restart service(s) (interactive multi-select, or -s to skip)
57
+ foundation-utils docker restart
57
58
  foundation-utils docker restart -s <service-name>
59
+ foundation-utils docker restart -s api worker
58
60
 
59
61
  # List containers (docker compose ps)
60
62
  foundation-utils docker list
63
+
64
+ # Container logs (interactive service picker; or pass -s / --all)
65
+ foundation-utils docker logs
66
+ foundation-utils docker logs --all
67
+ foundation-utils docker logs -s <service-name> --follow
68
+ foundation-utils docker logs -n 200
69
+
70
+ # Restore stack from a saved backup (interactive list of docker-compose_*.yaml)
71
+ foundation-utils docker restore
72
+ foundation-utils docker restore -d ./docker_image_backups
73
+ foundation-utils docker restore ./docker_image_backups/docker-compose_20260101T120000.yaml
74
+ foundation-utils docker restore --force
61
75
  ```
62
76
 
77
+ **docker logs** – Runs `docker compose logs`. With no `-s`, opens an interactive list (all services or a single service from `docker compose config --services`). Use `--all` to skip the picker and show every service. Use `-s, --service` to target one service without prompting. `--follow` and `-n, --tail` work as in Docker.
78
+
79
+ **docker restart** – Runs `docker compose restart`. With no `-s`, opens an interactive **checkbox** (space to toggle, enter to confirm) from `docker compose config --services`. Use `-s, --service <names...>` for one or more services without prompting, e.g. `-s api worker`.
80
+
81
+ **docker restore** – Lists backups under `./docker_image_backups` (newest first) and prompts you to pick one, then runs the same flow as `docker backup --restore`. Pass a path to skip the list. Use `-d, --dir` to scan another folder.
82
+
63
83
  ## Programmatic Usage
64
84
 
65
85
  ```typescript
@@ -73,7 +93,9 @@ import {
73
93
  dbRestore,
74
94
  dockerBackup,
75
95
  dockerList,
96
+ dockerLogs,
76
97
  dockerRestart,
98
+ dockerRestore,
77
99
  dockerUpdate
78
100
  } from '@tryhuset/foundation-utils';
79
101
 
@@ -105,8 +127,19 @@ await dockerUpdate({ force: true });
105
127
  // Restore stack from backup compose file (same as: docker backup --restore <path>)
106
128
  await dockerUpdate({ backupFile: './docker_image_backups/docker-compose_20260101T120000.yaml', force: true });
107
129
 
108
- // Restart a service
130
+ // Interactive restore (list backups, then pick) or pass a path
131
+ await dockerRestore();
132
+ await dockerRestore({ backupCompose: './docker_image_backups/docker-compose_20260101T120000.yaml' });
133
+
134
+ // Logs: interactive picker, or allServices / explicit service
135
+ await dockerLogs({ follow: true, tail: 200 });
136
+ await dockerLogs({ allServices: true, follow: true });
137
+ await dockerLogs({ follow: true, tail: 200, service: 'api' });
138
+
139
+ // Restart (interactive multi-select) or pass service(s)
140
+ await dockerRestart();
109
141
  await dockerRestart({ service: 'api' });
142
+ await dockerRestart({ services: ['api', 'worker'] });
110
143
 
111
144
  // List containers
112
145
  await dockerList();
@@ -1,3 +1,5 @@
1
+ /** Default directory for backup compose files and image info (see docker backup). */
2
+ export declare const DOCKER_IMAGE_BACKUP_DIR = "./docker_image_backups";
1
3
  export interface DockerBackupOptions {
2
4
  file?: string;
3
5
  }
@@ -3,7 +3,9 @@ import { existsSync, mkdirSync, writeFileSync, readFileSync } from 'fs';
3
3
  import { Chalk } from 'chalk';
4
4
  import { resolveComposeFile } from '../../utils/resolveComposeFile.js';
5
5
  const chalk = new Chalk();
6
- const BACKUP_DIR = './docker_image_backups';
6
+ /** Default directory for backup compose files and image info (see docker backup). */
7
+ export const DOCKER_IMAGE_BACKUP_DIR = './docker_image_backups';
8
+ const BACKUP_DIR = DOCKER_IMAGE_BACKUP_DIR;
7
9
  /**
8
10
  * Creates a backup of current Docker images (tags and compose file).
9
11
  * Does not pull or restart anything.
@@ -1 +1 @@
1
- {"version":3,"file":"backup.js","sourceRoot":"","sources":["../../../../src/commands/docker/backup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAExE,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAE9B,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AAEvE,MAAM,KAAK,GAAG,IAAI,KAAK,EAAE,CAAC;AAE1B,MAAM,UAAU,GAAG,wBAAwB,CAAC;AAM5C;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,WAAmB;IACpD,MAAM,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAE/E,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7C,CAAC;IAED,MAAM,cAAc,GAAG,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IACzD,IAAI,sBAAsB,GAAG,cAAc,CAAC;IAE5C,MAAM,QAAQ,GAAG,QAAQ,CAAC,sBAAsB,WAAW,iBAAiB,CAAC;SAC1E,QAAQ,EAAE;SACV,IAAI,EAAE;SACN,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACpB,MAAM,CAAC,OAAO,CAAC,CAAC;IAEnB,MAAM,aAAa,GAAG,GAAG,UAAU,eAAe,WAAW,MAAM,CAAC;IACpE,IAAI,SAAS,GAAG,yBAAyB,WAAW,IAAI,CAAC;IACzD,SAAS,IAAI,kDAAkD,CAAC;IAEhE,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,wBAAwB,OAAO,EAAE,CAAC,CAAC,CAAC;QAE3D,IAAI,CAAC;YACH,MAAM,WAAW,GAAG,QAAQ,CAAC,sBAAsB,WAAW,YAAY,OAAO,GAAG,CAAC;iBAClF,QAAQ,EAAE;iBACV,IAAI,EAAE,CAAC;YAEV,IAAI,WAAW,EAAE,CAAC;gBAChB,MAAM,OAAO,GAAG,QAAQ,CAAC,yCAAyC,WAAW,GAAG,CAAC;qBAC9E,QAAQ,EAAE;qBACV,IAAI,EAAE,CAAC;gBACV,MAAM,SAAS,GAAG,QAAQ,CAAC,gDAAgD,WAAW,GAAG,CAAC;qBACvF,QAAQ,EAAE;qBACV,IAAI,EAAE,CAAC;gBAEV,SAAS,IAAI,YAAY,OAAO,IAAI,CAAC;gBACrC,SAAS,IAAI,aAAa,OAAO,IAAI,CAAC;gBACtC,SAAS,IAAI,eAAe,SAAS,IAAI,CAAC;gBAC1C,SAAS,IAAI,OAAO,CAAC;gBAErB,IAAI,SAAS,EAAE,CAAC;oBACd,MAAM,SAAS,GAAG,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,WAAW,EAAE,CAAC;oBACrE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,SAAS,OAAO,SAAS,EAAE,CAAC,CAAC,CAAC;oBAChE,QAAQ,CAAC,eAAe,SAAS,MAAM,SAAS,GAAG,CAAC,CAAC;oBACrD,SAAS,IAAI,eAAe,SAAS,MAAM,CAAC;oBAE5C,MAAM,kBAAkB,GAAG,IAAI,MAAM,CACnC,aAAa,SAAS,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,EAAE,EAC/D,GAAG,CACJ,CAAC;oBACF,sBAAsB,GAAG,sBAAsB,CAAC,OAAO,CACrD,kBAAkB,EAClB,UAAU,SAAS,EAAE,CACtB,CAAC;gBACJ,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,sCAAsC,OAAO,EAAE,CAAC,CAAC,CAAC;YAC5E,SAAS;QACX,CAAC;IACH,CAAC;IAED,aAAa,CAAC,GAAG,UAAU,mBAAmB,WAAW,OAAO,EAAE,sBAAsB,CAAC,CAAC;IAC1F,aAAa,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;IACxC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,gDAAgD,aAAa,EAAE,CAAC,CAAC,CAAC;IAC1F,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,KAAK,CAAC,mCAAmC,UAAU,mBAAmB,WAAW,OAAO,CAAC,CAChG,CAAC;IACF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC;IAC/C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,oBAAoB,UAAU,EAAE,CAAC,CAAC,CAAC;IAC1D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,qBAAqB,WAAW,EAAE,CAAC,CAAC,CAAC;IAC5D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,oBAAoB,UAAU,eAAe,WAAW,MAAM,CAAC,CAAC,CAAC;IACxF,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,IAAI,CAAC,iCAAiC,UAAU,mBAAmB,WAAW,OAAO,CAAC,CAC7F,CAAC;IAEF,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,UAA+B,EAAE;IAClE,MAAM,WAAW,GAAG,kBAAkB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC,CAAC;IAC/D,kBAAkB,CAAC,WAAW,CAAC,CAAC;IAChC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC,CAAC;AAC7D,CAAC"}
1
+ {"version":3,"file":"backup.js","sourceRoot":"","sources":["../../../../src/commands/docker/backup.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /** Sentinel for logs picker: stream all services. */
2
+ export declare const ALL_SERVICES_LOGS_VALUE = "__all__";
3
+ export declare function listComposeServiceNames(composeFile: string): string[];
4
+ export declare function promptComposeServiceForLogs(composeFile: string): Promise<string | undefined>;
5
+ export declare function promptComposeServiceForRestart(composeFile: string): Promise<string[]>;
@@ -0,0 +1,58 @@
1
+ import { execSync } from 'child_process';
2
+ import { Chalk } from 'chalk';
3
+ import inquirer from 'inquirer';
4
+ import { exitProcess } from '../../utils/processExit.js';
5
+ const chalk = new Chalk();
6
+ /** Sentinel for logs picker: stream all services. */
7
+ export const ALL_SERVICES_LOGS_VALUE = '__all__';
8
+ export function listComposeServiceNames(composeFile) {
9
+ const out = execSync(`docker compose -f "${composeFile}" config --services`, {
10
+ encoding: 'utf8'
11
+ })
12
+ .trim()
13
+ .split('\n')
14
+ .map((s) => s.trim())
15
+ .filter(Boolean);
16
+ return [...new Set(out)].sort((a, b) => a.localeCompare(b));
17
+ }
18
+ export async function promptComposeServiceForLogs(composeFile) {
19
+ const services = listComposeServiceNames(composeFile);
20
+ if (services.length === 0) {
21
+ console.error(chalk.red('No services found in the compose file.'));
22
+ exitProcess(1);
23
+ }
24
+ console.log(chalk.blue(`Compose services (${composeFile}):`));
25
+ const { selected } = await inquirer.prompt([
26
+ {
27
+ type: 'list',
28
+ name: 'selected',
29
+ message: 'Select service for logs',
30
+ choices: [
31
+ { name: 'All services', value: ALL_SERVICES_LOGS_VALUE },
32
+ ...services.map((s) => ({ name: s, value: s }))
33
+ ],
34
+ pageSize: Math.min(20, Math.max(10, services.length + 1))
35
+ }
36
+ ]);
37
+ return selected === ALL_SERVICES_LOGS_VALUE ? undefined : selected;
38
+ }
39
+ export async function promptComposeServiceForRestart(composeFile) {
40
+ const services = listComposeServiceNames(composeFile);
41
+ if (services.length === 0) {
42
+ console.error(chalk.red('No services found in the compose file.'));
43
+ exitProcess(1);
44
+ }
45
+ console.log(chalk.blue(`Compose services (${composeFile}):`));
46
+ const { selected } = await inquirer.prompt([
47
+ {
48
+ type: 'checkbox',
49
+ name: 'selected',
50
+ message: 'Select service(s) to restart (space to toggle, enter to confirm)',
51
+ choices: services.map((s) => ({ name: s, value: s })),
52
+ pageSize: Math.min(20, Math.max(10, services.length)),
53
+ validate: (answer) => answer.length > 0 ? true : 'Select at least one service'
54
+ }
55
+ ]);
56
+ return selected;
57
+ }
58
+ //# sourceMappingURL=composeServices.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"composeServices.js","sourceRoot":"","sources":["../../../../src/commands/docker/composeServices.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,11 @@
1
1
  import type { Command } from 'commander';
2
2
  import { dockerBackup } from './backup.js';
3
3
  import { dockerList } from './list.js';
4
+ import { dockerLogs } from './logs.js';
4
5
  import { dockerRestart } from './restart.js';
6
+ import { dockerRestore } from './restore.js';
5
7
  import { dockerUpdate } from './update.js';
6
- export { dockerBackup, dockerList, dockerRestart, dockerUpdate };
8
+ export { dockerBackup, dockerList, dockerLogs, dockerRestart, dockerRestore, dockerUpdate };
7
9
  /**
8
10
  * Registers `docker` subcommands on the given Commander program.
9
11
  * @param program Commander root or parent command.
@@ -1,8 +1,10 @@
1
1
  import { dockerBackup } from './backup.js';
2
2
  import { dockerList } from './list.js';
3
+ import { dockerLogs } from './logs.js';
3
4
  import { dockerRestart } from './restart.js';
5
+ import { dockerRestore } from './restore.js';
4
6
  import { dockerUpdate } from './update.js';
5
- export { dockerBackup, dockerList, dockerRestart, dockerUpdate };
7
+ export { dockerBackup, dockerList, dockerLogs, dockerRestart, dockerRestore, dockerUpdate };
6
8
  /**
7
9
  * Registers `docker` subcommands on the given Commander program.
8
10
  * @param program Commander root or parent command.
@@ -38,14 +40,48 @@ export function registerDockerCommands(program) {
38
40
  }));
39
41
  docker
40
42
  .command('restart')
41
- .description('Restart a specific container/service')
42
- .requiredOption('-s, --service <name>', 'Service name to restart')
43
+ .description('Restart service(s) (interactive multi-select if no -s)')
44
+ .option('-s, --service <names...>', 'Service(s) to restart, e.g. -s api worker (skips interactive picker)')
43
45
  .option('-f, --file <path>', 'Path to compose file (default: ./compose.yaml)')
44
- .action((opts) => dockerRestart(opts));
46
+ .action((opts) => {
47
+ const raw = opts.service;
48
+ const services = raw === undefined ? undefined : Array.isArray(raw) ? raw : [raw];
49
+ return dockerRestart({ file: opts.file, services });
50
+ });
45
51
  docker
46
52
  .command('list')
47
53
  .description('List containers (docker compose ps)')
48
54
  .option('-f, --file <path>', 'Path to compose file (default: ./compose.yaml)')
49
55
  .action((opts) => dockerList(opts));
56
+ docker
57
+ .command('logs')
58
+ .description('Stream or print container logs (docker compose logs)')
59
+ .option('-f, --file <path>', 'Path to compose file (default: ./compose.yaml)')
60
+ .option('--follow', 'Follow log output')
61
+ .option('-n, --tail <n>', 'Number of lines to show from the end of the logs')
62
+ .option('-s, --service <name>', 'Service name (skips interactive picker)')
63
+ .option('--all', 'All services without prompting (skip the picker)')
64
+ .action((opts) => {
65
+ const tailNum = opts.tail !== undefined ? parseInt(opts.tail, 10) : undefined;
66
+ const tail = tailNum !== undefined && Number.isFinite(tailNum) && tailNum > 0 ? tailNum : undefined;
67
+ return dockerLogs({
68
+ file: opts.file,
69
+ follow: opts.follow,
70
+ tail,
71
+ service: opts.service,
72
+ allServices: opts.all === true
73
+ });
74
+ });
75
+ docker
76
+ .command('restore')
77
+ .description('Restore stack from a backup compose file (interactive list, or pass a path)')
78
+ .argument('[backup]', 'Path to backup compose file (optional)')
79
+ .option('-d, --dir <path>', 'Directory to scan for backups (default: ./docker_image_backups)')
80
+ .option('--force', 'Skip confirmation before restore')
81
+ .action((backup, opts) => dockerRestore({
82
+ backupCompose: backup,
83
+ backupDir: opts.dir,
84
+ force: opts.force
85
+ }));
50
86
  }
51
87
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/commands/docker/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,YAAY,EAAE,CAAC;AAEjE;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CAAC,OAAgB;IACrD,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC,2BAA2B,CAAC,CAAC;IAElF,MAAM;SACH,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,iEAAiE,CAAC;SAC9E,MAAM,CAAC,mBAAmB,EAAE,gDAAgD,CAAC;SAC7E,MAAM,CACL,kBAAkB,EAClB,wFAAwF,CACzF;SACA,MAAM,CAAC,SAAS,EAAE,yCAAyC,CAAC;SAC5D,MAAM,CAAC,CAAC,IAA0D,EAAE,EAAE;QACrE,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,OAAO,YAAY,CAAC;gBAClB,UAAU,EAAE,IAAI,CAAC,OAAO;gBACxB,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,QAAQ,EAAE,IAAI;aACf,CAAC,CAAC;QACL,CAAC;QACD,OAAO,YAAY,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEL,MAAM;SACH,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,oDAAoD,CAAC;SACjE,MAAM,CAAC,mBAAmB,EAAE,gDAAgD,CAAC;SAC7E,MAAM,CAAC,SAAS,EAAE,0BAA0B,CAAC;SAC7C,MAAM,CAAC,iBAAiB,EAAE,oCAAoC,CAAC;SAC/D,MAAM,CAAC,CAAC,IAA0D,EAAE,EAAE,CACrE,YAAY,CAAC;QACX,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,QAAQ,EAAE,IAAI,CAAC,MAAM,KAAK,KAAK;KAChC,CAAC,CACH,CAAC;IAEJ,MAAM;SACH,OAAO,CAAC,SAAS,CAAC;SAClB,WAAW,CAAC,sCAAsC,CAAC;SACnD,cAAc,CAAC,sBAAsB,EAAE,yBAAyB,CAAC;SACjE,MAAM,CAAC,mBAAmB,EAAE,gDAAgD,CAAC;SAC7E,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC;IAEzC,MAAM;SACH,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,qCAAqC,CAAC;SAClD,MAAM,CAAC,mBAAmB,EAAE,gDAAgD,CAAC;SAC7E,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;AACxC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/commands/docker/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ export interface DockerLogsOptions {
2
+ file?: string;
3
+ /** Follow log output (docker compose logs -f). */
4
+ follow?: boolean;
5
+ /** Number of lines from the end (docker compose logs --tail). */
6
+ tail?: number;
7
+ /** Compose service name; skips the picker when set. */
8
+ service?: string;
9
+ /**
10
+ * When true, show logs for all services without prompting.
11
+ * Use when `service` is omitted and you do not want the interactive picker.
12
+ */
13
+ allServices?: boolean;
14
+ }
15
+ /**
16
+ * Streams or prints logs from the compose stack (docker compose logs).
17
+ * With no service and without allServices, prompts for a service (or all).
18
+ * @param options Logs options.
19
+ */
20
+ export declare function dockerLogs(options?: DockerLogsOptions): Promise<void>;
@@ -0,0 +1,28 @@
1
+ import { execSync } from 'child_process';
2
+ import { resolveComposeFile } from '../../utils/resolveComposeFile.js';
3
+ import { promptComposeServiceForLogs } from './composeServices.js';
4
+ /**
5
+ * Streams or prints logs from the compose stack (docker compose logs).
6
+ * With no service and without allServices, prompts for a service (or all).
7
+ * @param options Logs options.
8
+ */
9
+ export async function dockerLogs(options = {}) {
10
+ const composeFile = resolveComposeFile(options.file);
11
+ const { follow, tail, allServices } = options;
12
+ let service = options.service;
13
+ if (!service && !allServices) {
14
+ service = await promptComposeServiceForLogs(composeFile);
15
+ }
16
+ const parts = [`docker compose -f "${composeFile}" logs`];
17
+ if (tail != null && tail > 0) {
18
+ parts.push(`--tail ${Math.floor(tail)}`);
19
+ }
20
+ if (follow) {
21
+ parts.push('-f');
22
+ }
23
+ if (service) {
24
+ parts.push(`"${service}"`);
25
+ }
26
+ execSync(parts.join(' '), { stdio: 'inherit' });
27
+ }
28
+ //# sourceMappingURL=logs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logs.js","sourceRoot":"","sources":["../../../../src/commands/docker/logs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AAEvE,OAAO,EAAE,2BAA2B,EAAE,MAAM,sBAAsB,CAAC;AAiBnE;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,UAA6B,EAAE;IAC9D,MAAM,WAAW,GAAG,kBAAkB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;IAE9C,IAAI,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAE9B,IAAI,CAAC,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC;QAC7B,OAAO,GAAG,MAAM,2BAA2B,CAAC,WAAW,CAAC,CAAC;IAC3D,CAAC;IAED,MAAM,KAAK,GAAG,CAAC,sBAAsB,WAAW,QAAQ,CAAC,CAAC;IAC1D,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,GAAG,CAAC,EAAE,CAAC;QAC7B,KAAK,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC3C,CAAC;IACD,IAAI,MAAM,EAAE,CAAC;QACX,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnB,CAAC;IACD,IAAI,OAAO,EAAE,CAAC;QACZ,KAAK,CAAC,IAAI,CAAC,IAAI,OAAO,GAAG,CAAC,CAAC;IAC7B,CAAC;IAED,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;AAClD,CAAC"}
@@ -1,11 +1,13 @@
1
1
  export interface DockerRestartOptions {
2
2
  file?: string;
3
- service: string;
3
+ /** One service (skips picker); merged with `services` if both are set. */
4
+ service?: string;
5
+ /** One or more services (skips picker when non-empty). */
6
+ services?: string[];
4
7
  }
5
8
  /**
6
- * Restarts a specific container/service in the compose stack.
9
+ * Restarts container(s) in the compose stack.
10
+ * With no explicit services, prompts for one or more (checkbox).
7
11
  * @param options Restart options.
8
- * @param [options.file] Path to compose file (default ./compose.yaml).
9
- * @param options.service Service name to restart.
10
12
  */
11
- export declare function dockerRestart(options: DockerRestartOptions): Promise<void>;
13
+ export declare function dockerRestart(options?: DockerRestartOptions): Promise<void>;
@@ -1,15 +1,27 @@
1
1
  import { execSync } from 'child_process';
2
2
  import { resolveComposeFile } from '../../utils/resolveComposeFile.js';
3
+ import { promptComposeServiceForRestart } from './composeServices.js';
4
+ function resolveExplicitServices(options) {
5
+ const merged = [...(options.services ?? []), ...(options.service ? [options.service] : [])];
6
+ const uniq = [...new Set(merged.map((s) => s.trim()).filter(Boolean))];
7
+ return uniq.length > 0 ? uniq : undefined;
8
+ }
9
+ function quoteServiceArg(name) {
10
+ return `"${name.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"`;
11
+ }
3
12
  /**
4
- * Restarts a specific container/service in the compose stack.
13
+ * Restarts container(s) in the compose stack.
14
+ * With no explicit services, prompts for one or more (checkbox).
5
15
  * @param options Restart options.
6
- * @param [options.file] Path to compose file (default ./compose.yaml).
7
- * @param options.service Service name to restart.
8
16
  */
9
- export async function dockerRestart(options) {
17
+ export async function dockerRestart(options = {}) {
10
18
  const composeFile = resolveComposeFile(options.file);
11
- const { service } = options;
12
- execSync(`docker compose -f "${composeFile}" restart "${service}"`, {
19
+ let services = resolveExplicitServices(options);
20
+ if (!services?.length) {
21
+ services = await promptComposeServiceForRestart(composeFile);
22
+ }
23
+ const restartArgs = services.map(quoteServiceArg).join(' ');
24
+ execSync(`docker compose -f "${composeFile}" restart ${restartArgs}`, {
13
25
  stdio: 'inherit'
14
26
  });
15
27
  }
@@ -1 +1 @@
1
- {"version":3,"file":"restart.js","sourceRoot":"","sources":["../../../../src/commands/docker/restart.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AAOvE;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAA6B;IAC/D,MAAM,WAAW,GAAG,kBAAkB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IAE5B,QAAQ,CAAC,sBAAsB,WAAW,cAAc,OAAO,GAAG,EAAE;QAClE,KAAK,EAAE,SAAS;KACjB,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"restart.js","sourceRoot":"","sources":["../../../../src/commands/docker/restart.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AAEvE,OAAO,EAAE,8BAA8B,EAAE,MAAM,sBAAsB,CAAC;AAUtE,SAAS,uBAAuB,CAAC,OAA6B;IAC5D,MAAM,MAAM,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5F,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACvE,OAAO,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;AAC5C,CAAC;AAED,SAAS,eAAe,CAAC,IAAY;IACnC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC;AACjE,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,UAAgC,EAAE;IACpE,MAAM,WAAW,GAAG,kBAAkB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAErD,IAAI,QAAQ,GAAG,uBAAuB,CAAC,OAAO,CAAC,CAAC;IAEhD,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;QACtB,QAAQ,GAAG,MAAM,8BAA8B,CAAC,WAAW,CAAC,CAAC;IAC/D,CAAC;IAED,MAAM,WAAW,GAAG,QAAQ,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC5D,QAAQ,CAAC,sBAAsB,WAAW,aAAa,WAAW,EAAE,EAAE;QACpE,KAAK,EAAE,SAAS;KACjB,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,13 @@
1
+ export interface DockerRestoreOptions {
2
+ /** Explicit backup compose file (skips interactive list). */
3
+ backupCompose?: string;
4
+ /** Directory to scan for docker-compose_*.yaml (default: ./docker_image_backups). */
5
+ backupDir?: string;
6
+ /** Skip confirmation before down/pull/up. */
7
+ force?: boolean;
8
+ }
9
+ /**
10
+ * Restores the stack from a backup compose file produced by docker backup.
11
+ * With no backup path, lists backups under the backup dir and prompts for one.
12
+ */
13
+ export declare function dockerRestore(options?: DockerRestoreOptions): Promise<void>;
@@ -0,0 +1,63 @@
1
+ import { existsSync, readdirSync, statSync } from 'fs';
2
+ import { join } from 'path';
3
+ import { Chalk } from 'chalk';
4
+ import inquirer from 'inquirer';
5
+ import { exitProcess } from '../../utils/processExit.js';
6
+ import { DOCKER_IMAGE_BACKUP_DIR } from './backup.js';
7
+ import { dockerUpdate } from './update.js';
8
+ const chalk = new Chalk();
9
+ const BACKUP_FILE_PREFIX = 'docker-compose_';
10
+ const BACKUP_FILE_SUFFIX = '.yaml';
11
+ function listBackupComposeFiles(backupDir) {
12
+ if (!existsSync(backupDir)) {
13
+ return [];
14
+ }
15
+ const entries = readdirSync(backupDir)
16
+ .filter((name) => name.startsWith(BACKUP_FILE_PREFIX) && name.endsWith(BACKUP_FILE_SUFFIX))
17
+ .map((name) => {
18
+ const fullPath = join(backupDir, name);
19
+ const mtimeMs = statSync(fullPath).mtimeMs;
20
+ const stampMatch = name.slice(BACKUP_FILE_PREFIX.length, -BACKUP_FILE_SUFFIX.length);
21
+ const date = new Date(mtimeMs);
22
+ const label = `${date.toLocaleString()} ${stampMatch}`;
23
+ return { path: fullPath, label, mtimeMs };
24
+ })
25
+ .sort((a, b) => b.mtimeMs - a.mtimeMs);
26
+ return entries.map(({ path, label }) => ({ path, label }));
27
+ }
28
+ /**
29
+ * Restores the stack from a backup compose file produced by docker backup.
30
+ * With no backup path, lists backups under the backup dir and prompts for one.
31
+ */
32
+ export async function dockerRestore(options = {}) {
33
+ const backupDir = options.backupDir ?? DOCKER_IMAGE_BACKUP_DIR;
34
+ let backupFile = options.backupCompose;
35
+ if (!backupFile) {
36
+ const choices = listBackupComposeFiles(backupDir);
37
+ if (choices.length === 0) {
38
+ console.error(chalk.red(`No backup compose files found in ${backupDir} (expected ${BACKUP_FILE_PREFIX}*${BACKUP_FILE_SUFFIX}). Run docker backup first.`));
39
+ exitProcess(1);
40
+ }
41
+ console.log(chalk.blue(`Backups in ${backupDir} (newest first):`));
42
+ const { selected } = await inquirer.prompt([
43
+ {
44
+ type: 'list',
45
+ name: 'selected',
46
+ message: 'Select backup to restore',
47
+ choices: choices.map((c) => ({ name: c.label, value: c.path })),
48
+ pageSize: Math.min(20, Math.max(10, choices.length))
49
+ }
50
+ ]);
51
+ backupFile = selected;
52
+ }
53
+ if (!existsSync(backupFile)) {
54
+ console.error(chalk.red(`Error: Backup compose file not found at ${backupFile}`));
55
+ exitProcess(1);
56
+ }
57
+ await dockerUpdate({
58
+ backupFile,
59
+ force: options.force,
60
+ noBackup: true
61
+ });
62
+ }
63
+ //# sourceMappingURL=restore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"restore.js","sourceRoot":"","sources":["../../../../src/commands/docker/restore.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import type { Command } from 'commander';
2
2
  export { dbEnd, dbExport, dbImport, dbList, dbRestore } from './db/index.js';
3
- export { dockerBackup, dockerList, dockerRestart, dockerUpdate } from './docker/index.js';
3
+ export { dockerBackup, dockerList, dockerLogs, dockerRestart, dockerRestore, dockerUpdate } from './docker/index.js';
4
4
  /**
5
5
  * Registers all foundation-utils CLI commands on the given Commander program.
6
6
  * @param program Commander program instance.
@@ -1,7 +1,7 @@
1
1
  import { registerDbCommands } from './db/index.js';
2
2
  import { registerDockerCommands } from './docker/index.js';
3
3
  export { dbEnd, dbExport, dbImport, dbList, dbRestore } from './db/index.js';
4
- export { dockerBackup, dockerList, dockerRestart, dockerUpdate } from './docker/index.js';
4
+ export { dockerBackup, dockerList, dockerLogs, dockerRestart, dockerRestore, dockerUpdate } from './docker/index.js';
5
5
  /**
6
6
  * Registers all foundation-utils CLI commands on the given Commander program.
7
7
  * @param program Commander program instance.
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAE3D,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE7E,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAE1F;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAgB;IAC/C,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAC5B,sBAAsB,CAAC,OAAO,CAAC,CAAC;AAClC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAE3D,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE7E,OAAO,EACL,YAAY,EACZ,UAAU,EACV,UAAU,EACV,aAAa,EACb,aAAa,EACb,YAAY,EACb,MAAM,mBAAmB,CAAC;AAE3B;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAgB;IAC/C,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAC5B,sBAAsB,CAAC,OAAO,CAAC,CAAC;AAClC,CAAC"}
@@ -1 +1 @@
1
- export { registerCommands, dbEnd, dbExport, dbImport, dbList, dbRestore, dockerBackup, dockerList, dockerRestart, dockerUpdate } from './commands/index.js';
1
+ export { registerCommands, dbEnd, dbExport, dbImport, dbList, dbRestore, dockerBackup, dockerList, dockerLogs, dockerRestart, dockerRestore, dockerUpdate } from './commands/index.js';
package/dist/src/index.js CHANGED
@@ -1,2 +1,2 @@
1
- export { registerCommands, dbEnd, dbExport, dbImport, dbList, dbRestore, dockerBackup, dockerList, dockerRestart, dockerUpdate } from './commands/index.js';
1
+ export { registerCommands, dbEnd, dbExport, dbImport, dbList, dbRestore, dockerBackup, dockerList, dockerLogs, dockerRestart, dockerRestore, dockerUpdate } from './commands/index.js';
2
2
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,MAAM,EACN,SAAS,EACT,YAAY,EACZ,UAAU,EACV,aAAa,EACb,YAAY,EACb,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,MAAM,EACN,SAAS,EACT,YAAY,EACZ,UAAU,EACV,UAAU,EACV,aAAa,EACb,aAAa,EACb,YAAY,EACb,MAAM,qBAAqB,CAAC"}