@enspirit/emb 0.17.5 → 0.18.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.
package/README.md CHANGED
@@ -14,7 +14,7 @@ $ npm install -g @enspirit/emb
14
14
  $ emb COMMAND
15
15
  running command...
16
16
  $ emb (--version)
17
- @enspirit/emb/0.17.5 darwin-arm64 node-v22.21.1
17
+ @enspirit/emb/0.18.0 darwin-arm64 node-v22.21.1
18
18
  $ emb --help [COMMAND]
19
19
  USAGE
20
20
  $ emb COMMAND
@@ -42,6 +42,7 @@ USAGE
42
42
  * [`emb kubernetes restart [DEPLOYMENT]`](#emb-kubernetes-restart-deployment)
43
43
  * [`emb kubernetes shell COMPONENT`](#emb-kubernetes-shell-component)
44
44
  * [`emb logs [COMPONENT]`](#emb-logs-component)
45
+ * [`emb logs archive [COMPONENT]`](#emb-logs-archive-component)
45
46
  * [`emb ps`](#emb-ps)
46
47
  * [`emb resources`](#emb-resources)
47
48
  * [`emb resources build [COMPONENT]`](#emb-resources-build-component)
@@ -112,7 +113,7 @@ EXAMPLES
112
113
  $ emb clean
113
114
  ```
114
115
 
115
- _See code: [src/commands/clean.ts](https://github.com/enspirit/emb/blob/v0.17.5/src/commands/clean.ts)_
116
+ _See code: [src/commands/clean.ts](https://github.com/enspirit/emb/blob/v0.18.0/src/commands/clean.ts)_
116
117
 
117
118
  ## `emb components`
118
119
 
@@ -137,7 +138,7 @@ EXAMPLES
137
138
  $ emb components
138
139
  ```
139
140
 
140
- _See code: [src/commands/components/index.ts](https://github.com/enspirit/emb/blob/v0.17.5/src/commands/components/index.ts)_
141
+ _See code: [src/commands/components/index.ts](https://github.com/enspirit/emb/blob/v0.18.0/src/commands/components/index.ts)_
141
142
 
142
143
  ## `emb components logs [COMPONENT]`
143
144
 
@@ -158,9 +159,6 @@ FLAGS
158
159
  DESCRIPTION
159
160
  Get components logs.
160
161
 
161
- ALIASES
162
- $ emb logs
163
-
164
162
  EXAMPLES
165
163
  $ emb components logs
166
164
 
@@ -171,7 +169,7 @@ EXAMPLES
171
169
  $ emb components logs --no-follow backend
172
170
  ```
173
171
 
174
- _See code: [src/commands/components/logs.ts](https://github.com/enspirit/emb/blob/v0.17.5/src/commands/components/logs.ts)_
172
+ _See code: [src/commands/components/logs.ts](https://github.com/enspirit/emb/blob/v0.18.0/src/commands/components/logs.ts)_
175
173
 
176
174
  ## `emb components shell COMPONENT`
177
175
 
@@ -199,7 +197,7 @@ EXAMPLES
199
197
  $ emb components shell
200
198
  ```
201
199
 
202
- _See code: [src/commands/components/shell.ts](https://github.com/enspirit/emb/blob/v0.17.5/src/commands/components/shell.ts)_
200
+ _See code: [src/commands/components/shell.ts](https://github.com/enspirit/emb/blob/v0.18.0/src/commands/components/shell.ts)_
203
201
 
204
202
  ## `emb config print`
205
203
 
@@ -224,7 +222,7 @@ EXAMPLES
224
222
  $ emb config print
225
223
  ```
226
224
 
227
- _See code: [src/commands/config/print.ts](https://github.com/enspirit/emb/blob/v0.17.5/src/commands/config/print.ts)_
225
+ _See code: [src/commands/config/print.ts](https://github.com/enspirit/emb/blob/v0.18.0/src/commands/config/print.ts)_
228
226
 
229
227
  ## `emb containers`
230
228
 
@@ -249,7 +247,7 @@ EXAMPLES
249
247
  $ emb containers
250
248
  ```
251
249
 
252
- _See code: [src/commands/containers/index.ts](https://github.com/enspirit/emb/blob/v0.17.5/src/commands/containers/index.ts)_
250
+ _See code: [src/commands/containers/index.ts](https://github.com/enspirit/emb/blob/v0.18.0/src/commands/containers/index.ts)_
253
251
 
254
252
  ## `emb containers prune`
255
253
 
@@ -273,7 +271,7 @@ EXAMPLES
273
271
  $ emb containers prune
274
272
  ```
275
273
 
276
- _See code: [src/commands/containers/prune.ts](https://github.com/enspirit/emb/blob/v0.17.5/src/commands/containers/prune.ts)_
274
+ _See code: [src/commands/containers/prune.ts](https://github.com/enspirit/emb/blob/v0.18.0/src/commands/containers/prune.ts)_
277
275
 
278
276
  ## `emb down`
279
277
 
@@ -298,7 +296,7 @@ EXAMPLES
298
296
  $ emb down
299
297
  ```
300
298
 
301
- _See code: [src/commands/down.ts](https://github.com/enspirit/emb/blob/v0.17.5/src/commands/down.ts)_
299
+ _See code: [src/commands/down.ts](https://github.com/enspirit/emb/blob/v0.18.0/src/commands/down.ts)_
302
300
 
303
301
  ## `emb help [COMMAND]`
304
302
 
@@ -344,7 +342,7 @@ EXAMPLES
344
342
  $ emb images
345
343
  ```
346
344
 
347
- _See code: [src/commands/images/index.ts](https://github.com/enspirit/emb/blob/v0.17.5/src/commands/images/index.ts)_
345
+ _See code: [src/commands/images/index.ts](https://github.com/enspirit/emb/blob/v0.18.0/src/commands/images/index.ts)_
348
346
 
349
347
  ## `emb images delete`
350
348
 
@@ -369,7 +367,7 @@ EXAMPLES
369
367
  $ emb images delete
370
368
  ```
371
369
 
372
- _See code: [src/commands/images/delete.ts](https://github.com/enspirit/emb/blob/v0.17.5/src/commands/images/delete.ts)_
370
+ _See code: [src/commands/images/delete.ts](https://github.com/enspirit/emb/blob/v0.18.0/src/commands/images/delete.ts)_
373
371
 
374
372
  ## `emb images prune`
375
373
 
@@ -394,7 +392,7 @@ EXAMPLES
394
392
  $ emb images prune
395
393
  ```
396
394
 
397
- _See code: [src/commands/images/prune.ts](https://github.com/enspirit/emb/blob/v0.17.5/src/commands/images/prune.ts)_
395
+ _See code: [src/commands/images/prune.ts](https://github.com/enspirit/emb/blob/v0.18.0/src/commands/images/prune.ts)_
398
396
 
399
397
  ## `emb images push`
400
398
 
@@ -423,7 +421,7 @@ EXAMPLES
423
421
  $ emb images push --registry my.registry.io --retag newtag
424
422
  ```
425
423
 
426
- _See code: [src/commands/images/push.ts](https://github.com/enspirit/emb/blob/v0.17.5/src/commands/images/push.ts)_
424
+ _See code: [src/commands/images/push.ts](https://github.com/enspirit/emb/blob/v0.18.0/src/commands/images/push.ts)_
427
425
 
428
426
  ## `emb kubernetes logs COMPONENT`
429
427
 
@@ -445,14 +443,11 @@ FLAGS
445
443
  DESCRIPTION
446
444
  Follow kubernetes logs.
447
445
 
448
- ALIASES
449
- $ emb logs
450
-
451
446
  EXAMPLES
452
447
  $ emb kubernetes logs
453
448
  ```
454
449
 
455
- _See code: [src/commands/kubernetes/logs.ts](https://github.com/enspirit/emb/blob/v0.17.5/src/commands/kubernetes/logs.ts)_
450
+ _See code: [src/commands/kubernetes/logs.ts](https://github.com/enspirit/emb/blob/v0.18.0/src/commands/kubernetes/logs.ts)_
456
451
 
457
452
  ## `emb kubernetes ps`
458
453
 
@@ -475,7 +470,7 @@ EXAMPLES
475
470
  $ emb kubernetes ps
476
471
  ```
477
472
 
478
- _See code: [src/commands/kubernetes/ps.ts](https://github.com/enspirit/emb/blob/v0.17.5/src/commands/kubernetes/ps.ts)_
473
+ _See code: [src/commands/kubernetes/ps.ts](https://github.com/enspirit/emb/blob/v0.18.0/src/commands/kubernetes/ps.ts)_
479
474
 
480
475
  ## `emb kubernetes restart [DEPLOYMENT]`
481
476
 
@@ -500,7 +495,7 @@ EXAMPLES
500
495
  $ emb kubernetes restart
501
496
  ```
502
497
 
503
- _See code: [src/commands/kubernetes/restart.ts](https://github.com/enspirit/emb/blob/v0.17.5/src/commands/kubernetes/restart.ts)_
498
+ _See code: [src/commands/kubernetes/restart.ts](https://github.com/enspirit/emb/blob/v0.18.0/src/commands/kubernetes/restart.ts)_
504
499
 
505
500
  ## `emb kubernetes shell COMPONENT`
506
501
 
@@ -529,7 +524,7 @@ EXAMPLES
529
524
  $ emb kubernetes shell
530
525
  ```
531
526
 
532
- _See code: [src/commands/kubernetes/shell.ts](https://github.com/enspirit/emb/blob/v0.17.5/src/commands/kubernetes/shell.ts)_
527
+ _See code: [src/commands/kubernetes/shell.ts](https://github.com/enspirit/emb/blob/v0.18.0/src/commands/kubernetes/shell.ts)_
533
528
 
534
529
  ## `emb logs [COMPONENT]`
535
530
 
@@ -550,9 +545,6 @@ FLAGS
550
545
  DESCRIPTION
551
546
  Get components logs.
552
547
 
553
- ALIASES
554
- $ emb logs
555
-
556
548
  EXAMPLES
557
549
  $ emb logs
558
550
 
@@ -563,6 +555,44 @@ EXAMPLES
563
555
  $ emb logs --no-follow backend
564
556
  ```
565
557
 
558
+ _See code: [src/commands/logs/index.ts](https://github.com/enspirit/emb/blob/v0.18.0/src/commands/logs/index.ts)_
559
+
560
+ ## `emb logs archive [COMPONENT]`
561
+
562
+ Archive docker compose logs to files (one file per component).
563
+
564
+ ```
565
+ USAGE
566
+ $ emb logs archive [COMPONENT...] [--json] [--verbose] [-C <value>] [-t] [--tail <value>] [-o <value>]
567
+
568
+ ARGUMENTS
569
+ [COMPONENT...] The component(s) to archive logs for (all if omitted)
570
+
571
+ FLAGS
572
+ -C, --root=<value> Run as if emb was started in <path>. Can also be set via EMB_ROOT env var.
573
+ -o, --output=<value> Output directory for log files (defaults to .emb/<flavor>/logs/docker/compose)
574
+ -t, --timestamps Include timestamps in logs
575
+ --tail=<value> Number of lines to show from the end of the logs
576
+ --[no-]verbose
577
+
578
+ GLOBAL FLAGS
579
+ --json Format output as json.
580
+
581
+ DESCRIPTION
582
+ Archive docker compose logs to files (one file per component).
583
+
584
+ EXAMPLES
585
+ $ emb logs archive
586
+
587
+ $ emb logs archive backend frontend
588
+
589
+ $ emb logs archive --timestamps
590
+
591
+ $ emb logs archive --tail 1000
592
+ ```
593
+
594
+ _See code: [src/commands/logs/archive.ts](https://github.com/enspirit/emb/blob/v0.18.0/src/commands/logs/archive.ts)_
595
+
566
596
  ## `emb ps`
567
597
 
568
598
  Lists the containers running in the project.
@@ -584,7 +614,7 @@ EXAMPLES
584
614
  $ emb ps
585
615
  ```
586
616
 
587
- _See code: [src/commands/ps.ts](https://github.com/enspirit/emb/blob/v0.17.5/src/commands/ps.ts)_
617
+ _See code: [src/commands/ps.ts](https://github.com/enspirit/emb/blob/v0.18.0/src/commands/ps.ts)_
588
618
 
589
619
  ## `emb resources`
590
620
 
@@ -609,7 +639,7 @@ EXAMPLES
609
639
  $ emb resources
610
640
  ```
611
641
 
612
- _See code: [src/commands/resources/index.ts](https://github.com/enspirit/emb/blob/v0.17.5/src/commands/resources/index.ts)_
642
+ _See code: [src/commands/resources/index.ts](https://github.com/enspirit/emb/blob/v0.18.0/src/commands/resources/index.ts)_
613
643
 
614
644
  ## `emb resources build [COMPONENT]`
615
645
 
@@ -639,7 +669,7 @@ EXAMPLES
639
669
  $ emb resources build build --flavor development
640
670
  ```
641
671
 
642
- _See code: [src/commands/resources/build.ts](https://github.com/enspirit/emb/blob/v0.17.5/src/commands/resources/build.ts)_
672
+ _See code: [src/commands/resources/build.ts](https://github.com/enspirit/emb/blob/v0.18.0/src/commands/resources/build.ts)_
643
673
 
644
674
  ## `emb restart [COMPONENT]`
645
675
 
@@ -667,7 +697,7 @@ EXAMPLES
667
697
  $ emb restart
668
698
  ```
669
699
 
670
- _See code: [src/commands/restart.ts](https://github.com/enspirit/emb/blob/v0.17.5/src/commands/restart.ts)_
700
+ _See code: [src/commands/restart.ts](https://github.com/enspirit/emb/blob/v0.18.0/src/commands/restart.ts)_
671
701
 
672
702
  ## `emb run TASK`
673
703
 
@@ -725,7 +755,7 @@ EXAMPLES
725
755
  $ emb secrets --json
726
756
  ```
727
757
 
728
- _See code: [src/commands/secrets/index.ts](https://github.com/enspirit/emb/blob/v0.17.5/src/commands/secrets/index.ts)_
758
+ _See code: [src/commands/secrets/index.ts](https://github.com/enspirit/emb/blob/v0.18.0/src/commands/secrets/index.ts)_
729
759
 
730
760
  ## `emb secrets providers`
731
761
 
@@ -750,7 +780,7 @@ EXAMPLES
750
780
  $ emb secrets providers
751
781
  ```
752
782
 
753
- _See code: [src/commands/secrets/providers.ts](https://github.com/enspirit/emb/blob/v0.17.5/src/commands/secrets/providers.ts)_
783
+ _See code: [src/commands/secrets/providers.ts](https://github.com/enspirit/emb/blob/v0.18.0/src/commands/secrets/providers.ts)_
754
784
 
755
785
  ## `emb secrets validate`
756
786
 
@@ -780,7 +810,7 @@ EXAMPLES
780
810
  $ emb secrets validate --json
781
811
  ```
782
812
 
783
- _See code: [src/commands/secrets/validate.ts](https://github.com/enspirit/emb/blob/v0.17.5/src/commands/secrets/validate.ts)_
813
+ _See code: [src/commands/secrets/validate.ts](https://github.com/enspirit/emb/blob/v0.18.0/src/commands/secrets/validate.ts)_
784
814
 
785
815
  ## `emb shell COMPONENT`
786
816
 
@@ -833,7 +863,7 @@ EXAMPLES
833
863
  $ emb start
834
864
  ```
835
865
 
836
- _See code: [src/commands/start.ts](https://github.com/enspirit/emb/blob/v0.17.5/src/commands/start.ts)_
866
+ _See code: [src/commands/start.ts](https://github.com/enspirit/emb/blob/v0.18.0/src/commands/start.ts)_
837
867
 
838
868
  ## `emb stop`
839
869
 
@@ -858,7 +888,7 @@ EXAMPLES
858
888
  $ emb stop
859
889
  ```
860
890
 
861
- _See code: [src/commands/stop.ts](https://github.com/enspirit/emb/blob/v0.17.5/src/commands/stop.ts)_
891
+ _See code: [src/commands/stop.ts](https://github.com/enspirit/emb/blob/v0.18.0/src/commands/stop.ts)_
862
892
 
863
893
  ## `emb tasks`
864
894
 
@@ -882,7 +912,7 @@ EXAMPLES
882
912
  $ emb tasks
883
913
  ```
884
914
 
885
- _See code: [src/commands/tasks/index.ts](https://github.com/enspirit/emb/blob/v0.17.5/src/commands/tasks/index.ts)_
915
+ _See code: [src/commands/tasks/index.ts](https://github.com/enspirit/emb/blob/v0.18.0/src/commands/tasks/index.ts)_
886
916
 
887
917
  ## `emb tasks run TASK`
888
918
 
@@ -915,7 +945,7 @@ EXAMPLES
915
945
  $ emb tasks run
916
946
  ```
917
947
 
918
- _See code: [src/commands/tasks/run.ts](https://github.com/enspirit/emb/blob/v0.17.5/src/commands/tasks/run.ts)_
948
+ _See code: [src/commands/tasks/run.ts](https://github.com/enspirit/emb/blob/v0.18.0/src/commands/tasks/run.ts)_
919
949
 
920
950
  ## `emb up [COMPONENT]`
921
951
 
@@ -944,7 +974,7 @@ EXAMPLES
944
974
  $ emb up
945
975
  ```
946
976
 
947
- _See code: [src/commands/up.ts](https://github.com/enspirit/emb/blob/v0.17.5/src/commands/up.ts)_
977
+ _See code: [src/commands/up.ts](https://github.com/enspirit/emb/blob/v0.18.0/src/commands/up.ts)_
948
978
 
949
979
  ## `emb update [CHANNEL]`
950
980
 
@@ -1,6 +1,5 @@
1
1
  import { BaseCommand } from '../../index.js';
2
2
  export default class ComponentsLogs extends BaseCommand {
3
- static aliases: string[];
4
3
  static description: string;
5
4
  static enableJsonFlag: boolean;
6
5
  static examples: string[];
@@ -2,7 +2,6 @@ import { Args, Flags } from '@oclif/core';
2
2
  import { BaseCommand, getContext } from '../../index.js';
3
3
  import { ComposeLogsOperation } from '../../../docker/index.js';
4
4
  export default class ComponentsLogs extends BaseCommand {
5
- static aliases = ['logs'];
6
5
  static description = 'Get components logs.';
7
6
  static enableJsonFlag = false;
8
7
  static examples = [
@@ -1,6 +1,5 @@
1
1
  import { KubernetesCommand } from '../../index.js';
2
2
  export default class KubernetesLogs extends KubernetesCommand {
3
- static aliases: string[];
4
3
  static description: string;
5
4
  static enableJsonFlag: boolean;
6
5
  static examples: string[];
@@ -4,7 +4,6 @@ import { PassThrough } from 'node:stream';
4
4
  import { KubernetesCommand } from '../../index.js';
5
5
  import { GetDeploymentPodsOperation } from '../../../kubernetes/operations/GetDeploymentPodsOperation.js';
6
6
  export default class KubernetesLogs extends KubernetesCommand {
7
- static aliases = ['logs'];
8
7
  static description = 'Follow kubernetes logs.';
9
8
  static enableJsonFlag = false;
10
9
  static examples = ['<%= config.bin %> <%= command.id %>'];
@@ -0,0 +1,16 @@
1
+ import { BaseCommand } from '../../index.js';
2
+ export default class LogsArchive extends BaseCommand {
3
+ static description: string;
4
+ static enableJsonFlag: boolean;
5
+ static examples: string[];
6
+ static strict: boolean;
7
+ static flags: {
8
+ timestamps: import("@oclif/core/interfaces").BooleanFlag<boolean>;
9
+ tail: import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
10
+ output: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
+ };
12
+ static args: {
13
+ component: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
14
+ };
15
+ run(): Promise<void>;
16
+ }
@@ -0,0 +1,59 @@
1
+ import { Args, Flags } from '@oclif/core';
2
+ import { BaseCommand, getContext } from '../../index.js';
3
+ import { ComposeLogsArchiveOperation } from '../../../docker/index.js';
4
+ export default class LogsArchive extends BaseCommand {
5
+ static description = 'Archive docker compose logs to files (one file per component).';
6
+ static enableJsonFlag = true;
7
+ static examples = [
8
+ '<%= config.bin %> <%= command.id %>',
9
+ '<%= config.bin %> <%= command.id %> backend frontend',
10
+ '<%= config.bin %> <%= command.id %> --timestamps',
11
+ '<%= config.bin %> <%= command.id %> --tail 1000',
12
+ ];
13
+ static strict = false;
14
+ static flags = {
15
+ timestamps: Flags.boolean({
16
+ char: 't',
17
+ description: 'Include timestamps in logs',
18
+ default: false,
19
+ }),
20
+ tail: Flags.integer({
21
+ description: 'Number of lines to show from the end of the logs',
22
+ }),
23
+ output: Flags.string({
24
+ char: 'o',
25
+ description: 'Output directory for log files (defaults to .emb/<flavor>/logs/docker/compose)',
26
+ }),
27
+ };
28
+ static args = {
29
+ component: Args.string({
30
+ name: 'component',
31
+ description: 'The component(s) to archive logs for (all if omitted)',
32
+ required: false,
33
+ }),
34
+ };
35
+ async run() {
36
+ const { flags, argv } = await this.parse(LogsArchive);
37
+ const { monorepo } = await getContext();
38
+ const componentNames = argv;
39
+ // Validate that all specified components exist
40
+ if (componentNames.length > 0) {
41
+ componentNames.forEach((name) => monorepo.component(name));
42
+ }
43
+ const result = await monorepo.run(new ComposeLogsArchiveOperation(), {
44
+ components: componentNames.length > 0 ? componentNames : undefined,
45
+ outputDir: flags.output,
46
+ timestamps: flags.timestamps,
47
+ tail: flags.tail,
48
+ });
49
+ if (this.jsonEnabled()) {
50
+ this.log(JSON.stringify(result, null, 2));
51
+ }
52
+ else {
53
+ this.log('Archived logs:');
54
+ for (const file of result) {
55
+ this.log(` ${file.component}: ${file.path}`);
56
+ }
57
+ }
58
+ }
59
+ }
@@ -0,0 +1,14 @@
1
+ import { BaseCommand } from '../../index.js';
2
+ export default class Logs extends BaseCommand {
3
+ static description: string;
4
+ static enableJsonFlag: boolean;
5
+ static examples: string[];
6
+ static strict: boolean;
7
+ static flags: {
8
+ follow: import("@oclif/core/interfaces").BooleanFlag<boolean>;
9
+ };
10
+ static args: {
11
+ component: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
12
+ };
13
+ run(): Promise<void>;
14
+ }
@@ -0,0 +1,44 @@
1
+ import { Args, Flags } from '@oclif/core';
2
+ import { BaseCommand, getContext } from '../../index.js';
3
+ import { ComposeLogsOperation } from '../../../docker/index.js';
4
+ export default class Logs extends BaseCommand {
5
+ static description = 'Get components logs.';
6
+ static enableJsonFlag = false;
7
+ static examples = [
8
+ '<%= config.bin %> <%= command.id %>',
9
+ '<%= config.bin %> <%= command.id %> backend',
10
+ '<%= config.bin %> <%= command.id %> backend frontend',
11
+ '<%= config.bin %> <%= command.id %> --no-follow backend',
12
+ ];
13
+ static strict = false;
14
+ static flags = {
15
+ follow: Flags.boolean({
16
+ name: 'follow',
17
+ char: 'f',
18
+ allowNo: true,
19
+ description: 'Follow log output',
20
+ default: true,
21
+ }),
22
+ };
23
+ static args = {
24
+ component: Args.string({
25
+ name: 'component',
26
+ description: 'The component(s) you want to see the logs of (all if omitted)',
27
+ required: false,
28
+ }),
29
+ };
30
+ async run() {
31
+ const { flags, argv } = await this.parse(Logs);
32
+ const { monorepo } = await getContext();
33
+ const componentNames = argv;
34
+ // Validate that all specified components exist
35
+ const services = componentNames.map((name) => {
36
+ const component = monorepo.component(name);
37
+ return component.name;
38
+ });
39
+ await monorepo.run(new ComposeLogsOperation(), {
40
+ services: services.length > 0 ? services : undefined,
41
+ follow: flags.follow,
42
+ });
43
+ }
44
+ }
@@ -0,0 +1,17 @@
1
+ import * as z from 'zod';
2
+ import { AbstractOperation } from '../../../operations/index.js';
3
+ export declare const ComposeLogsArchiveOperationInputSchema: z.ZodOptional<z.ZodObject<{
4
+ components: z.ZodOptional<z.ZodArray<z.ZodString>>;
5
+ outputDir: z.ZodOptional<z.ZodString>;
6
+ timestamps: z.ZodOptional<z.ZodBoolean>;
7
+ tail: z.ZodOptional<z.ZodNumber>;
8
+ }, z.core.$strip>>;
9
+ export interface ArchivedLogFile {
10
+ component: string;
11
+ path: string;
12
+ }
13
+ export declare class ComposeLogsArchiveOperation extends AbstractOperation<typeof ComposeLogsArchiveOperationInputSchema, ArchivedLogFile[]> {
14
+ constructor();
15
+ protected _run(input: z.input<typeof ComposeLogsArchiveOperationInputSchema>): Promise<ArchivedLogFile[]>;
16
+ private archiveComponentLogs;
17
+ }
@@ -0,0 +1,77 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { createWriteStream } from 'node:fs';
3
+ import { mkdir } from 'node:fs/promises';
4
+ import { dirname, join } from 'node:path';
5
+ import * as z from 'zod';
6
+ import { AbstractOperation } from '../../../operations/index.js';
7
+ export const ComposeLogsArchiveOperationInputSchema = z
8
+ .object({
9
+ components: z
10
+ .array(z.string())
11
+ .optional()
12
+ .describe('The list of components to archive logs for (all if omitted)'),
13
+ outputDir: z
14
+ .string()
15
+ .optional()
16
+ .describe('Output directory for log files (defaults to .emb/<flavor>/logs/docker/compose)'),
17
+ timestamps: z.boolean().optional().describe('Include timestamps in logs'),
18
+ tail: z
19
+ .number()
20
+ .optional()
21
+ .describe('Number of lines to show from the end'),
22
+ })
23
+ .optional();
24
+ export class ComposeLogsArchiveOperation extends AbstractOperation {
25
+ constructor() {
26
+ super(ComposeLogsArchiveOperationInputSchema);
27
+ }
28
+ async _run(input) {
29
+ const { monorepo } = this.context;
30
+ // Determine which components to archive
31
+ const componentNames = input?.components ?? monorepo.components.map((c) => c.name);
32
+ // Validate all component names
33
+ const components = componentNames.map((name) => monorepo.component(name));
34
+ // Determine output directory
35
+ const outputDir = input?.outputDir ?? monorepo.store.join('logs/docker/compose');
36
+ // Ensure output directory exists
37
+ await mkdir(outputDir, { recursive: true });
38
+ // Archive logs for each component
39
+ const archivePromises = components.map(async (component) => {
40
+ const logPath = join(outputDir, `${component.name}.log`);
41
+ await this.archiveComponentLogs(component.name, logPath, input);
42
+ return { component: component.name, path: logPath };
43
+ });
44
+ return Promise.all(archivePromises);
45
+ }
46
+ async archiveComponentLogs(serviceName, outputPath, input) {
47
+ const { monorepo } = this.context;
48
+ // Ensure parent directory exists
49
+ await mkdir(dirname(outputPath), { recursive: true });
50
+ const cmd = 'docker';
51
+ const args = ['compose', 'logs', '--no-color'];
52
+ if (input?.timestamps) {
53
+ args.push('-t');
54
+ }
55
+ if (input?.tail !== undefined) {
56
+ args.push('--tail', String(input.tail));
57
+ }
58
+ args.push(serviceName);
59
+ return new Promise((resolve, reject) => {
60
+ const writeStream = createWriteStream(outputPath);
61
+ const child = spawn(cmd, args, {
62
+ stdio: ['ignore', 'pipe', 'pipe'],
63
+ cwd: monorepo.rootDir,
64
+ });
65
+ child.stdout?.pipe(writeStream, { end: false });
66
+ child.stderr?.pipe(writeStream, { end: false });
67
+ child.on('error', (err) => {
68
+ writeStream.end();
69
+ reject(new Error(`Failed to get logs for ${serviceName}: ${err.message}`));
70
+ });
71
+ child.on('exit', () => {
72
+ writeStream.end();
73
+ resolve();
74
+ });
75
+ });
76
+ }
77
+ }
@@ -1,6 +1,7 @@
1
1
  export * from './ComposeDownOperation.js';
2
2
  export * from './ComposeExecOperation.js';
3
3
  export * from './ComposeExecShellOperation.js';
4
+ export * from './ComposeLogsArchiveOperation.js';
4
5
  export * from './ComposeLogsOperation.js';
5
6
  export * from './ComposePsOperation.js';
6
7
  export * from './ComposeRestartOperation.js';
@@ -1,6 +1,7 @@
1
1
  export * from './ComposeDownOperation.js';
2
2
  export * from './ComposeExecOperation.js';
3
3
  export * from './ComposeExecShellOperation.js';
4
+ export * from './ComposeLogsArchiveOperation.js';
4
5
  export * from './ComposeLogsOperation.js';
5
6
  export * from './ComposePsOperation.js';
6
7
  export * from './ComposeRestartOperation.js';
@@ -454,9 +454,7 @@
454
454
  ]
455
455
  },
456
456
  "components:logs": {
457
- "aliases": [
458
- "logs"
459
- ],
457
+ "aliases": [],
460
458
  "args": {
461
459
  "component": {
462
460
  "description": "The component(s) you want to see the logs of (all if omitted)",
@@ -978,9 +976,7 @@
978
976
  ]
979
977
  },
980
978
  "kubernetes:logs": {
981
- "aliases": [
982
- "logs"
983
- ],
979
+ "aliases": [],
984
980
  "args": {
985
981
  "component": {
986
982
  "description": "The component you want to see the logs of",
@@ -1235,13 +1231,21 @@
1235
1231
  "shell.js"
1236
1232
  ]
1237
1233
  },
1238
- "secrets": {
1234
+ "logs:archive": {
1239
1235
  "aliases": [],
1240
- "args": {},
1241
- "description": "List all secret references in the configuration.",
1236
+ "args": {
1237
+ "component": {
1238
+ "description": "The component(s) to archive logs for (all if omitted)",
1239
+ "name": "component",
1240
+ "required": false
1241
+ }
1242
+ },
1243
+ "description": "Archive docker compose logs to files (one file per component).",
1242
1244
  "examples": [
1243
1245
  "<%= config.bin %> <%= command.id %>",
1244
- "<%= config.bin %> <%= command.id %> --json"
1246
+ "<%= config.bin %> <%= command.id %> backend frontend",
1247
+ "<%= config.bin %> <%= command.id %> --timestamps",
1248
+ "<%= config.bin %> <%= command.id %> --tail 1000"
1245
1249
  ],
1246
1250
  "flags": {
1247
1251
  "json": {
@@ -1265,66 +1269,24 @@
1265
1269
  "multiple": false,
1266
1270
  "type": "option"
1267
1271
  },
1268
- "flavor": {
1269
- "description": "Specify the flavor to use.",
1270
- "name": "flavor",
1271
- "required": false,
1272
- "hasDynamicHelp": false,
1273
- "multiple": false,
1274
- "type": "option"
1275
- }
1276
- },
1277
- "hasDynamicHelp": false,
1278
- "hiddenAliases": [],
1279
- "id": "secrets",
1280
- "pluginAlias": "@enspirit/emb",
1281
- "pluginName": "@enspirit/emb",
1282
- "pluginType": "core",
1283
- "strict": true,
1284
- "enableJsonFlag": true,
1285
- "isESM": true,
1286
- "relativePath": [
1287
- "dist",
1288
- "src",
1289
- "cli",
1290
- "commands",
1291
- "secrets",
1292
- "index.js"
1293
- ]
1294
- },
1295
- "secrets:providers": {
1296
- "aliases": [],
1297
- "args": {},
1298
- "description": "Show configured secret providers and their status.",
1299
- "examples": [
1300
- "<%= config.bin %> <%= command.id %>"
1301
- ],
1302
- "flags": {
1303
- "json": {
1304
- "description": "Format output as json.",
1305
- "helpGroup": "GLOBAL",
1306
- "name": "json",
1272
+ "timestamps": {
1273
+ "char": "t",
1274
+ "description": "Include timestamps in logs",
1275
+ "name": "timestamps",
1307
1276
  "allowNo": false,
1308
1277
  "type": "boolean"
1309
1278
  },
1310
- "verbose": {
1311
- "name": "verbose",
1312
- "allowNo": true,
1313
- "type": "boolean"
1314
- },
1315
- "root": {
1316
- "char": "C",
1317
- "description": "Run as if emb was started in <path>. Can also be set via EMB_ROOT env var.",
1318
- "name": "root",
1319
- "required": false,
1279
+ "tail": {
1280
+ "description": "Number of lines to show from the end of the logs",
1281
+ "name": "tail",
1320
1282
  "hasDynamicHelp": false,
1321
1283
  "multiple": false,
1322
1284
  "type": "option"
1323
1285
  },
1324
- "flavor": {
1325
- "description": "Specify the flavor to use.",
1326
- "name": "flavor",
1327
- "required": false,
1286
+ "output": {
1287
+ "char": "o",
1288
+ "description": "Output directory for log files (defaults to .emb/<flavor>/logs/docker/compose)",
1289
+ "name": "output",
1328
1290
  "hasDynamicHelp": false,
1329
1291
  "multiple": false,
1330
1292
  "type": "option"
@@ -1332,11 +1294,11 @@
1332
1294
  },
1333
1295
  "hasDynamicHelp": false,
1334
1296
  "hiddenAliases": [],
1335
- "id": "secrets:providers",
1297
+ "id": "logs:archive",
1336
1298
  "pluginAlias": "@enspirit/emb",
1337
1299
  "pluginName": "@enspirit/emb",
1338
1300
  "pluginType": "core",
1339
- "strict": true,
1301
+ "strict": false,
1340
1302
  "enableJsonFlag": true,
1341
1303
  "isESM": true,
1342
1304
  "relativePath": [
@@ -1344,27 +1306,27 @@
1344
1306
  "src",
1345
1307
  "cli",
1346
1308
  "commands",
1347
- "secrets",
1348
- "providers.js"
1309
+ "logs",
1310
+ "archive.js"
1349
1311
  ]
1350
1312
  },
1351
- "secrets:validate": {
1313
+ "logs": {
1352
1314
  "aliases": [],
1353
- "args": {},
1354
- "description": "Validate that all secret references can be resolved (without showing values).",
1315
+ "args": {
1316
+ "component": {
1317
+ "description": "The component(s) you want to see the logs of (all if omitted)",
1318
+ "name": "component",
1319
+ "required": false
1320
+ }
1321
+ },
1322
+ "description": "Get components logs.",
1355
1323
  "examples": [
1356
1324
  "<%= config.bin %> <%= command.id %>",
1357
- "<%= config.bin %> <%= command.id %> --fail-fast",
1358
- "<%= config.bin %> <%= command.id %> --json"
1325
+ "<%= config.bin %> <%= command.id %> backend",
1326
+ "<%= config.bin %> <%= command.id %> backend frontend",
1327
+ "<%= config.bin %> <%= command.id %> --no-follow backend"
1359
1328
  ],
1360
1329
  "flags": {
1361
- "json": {
1362
- "description": "Format output as json.",
1363
- "helpGroup": "GLOBAL",
1364
- "name": "json",
1365
- "allowNo": false,
1366
- "type": "boolean"
1367
- },
1368
1330
  "verbose": {
1369
1331
  "name": "verbose",
1370
1332
  "allowNo": true,
@@ -1379,37 +1341,30 @@
1379
1341
  "multiple": false,
1380
1342
  "type": "option"
1381
1343
  },
1382
- "flavor": {
1383
- "description": "Specify the flavor to use.",
1384
- "name": "flavor",
1385
- "required": false,
1386
- "hasDynamicHelp": false,
1387
- "multiple": false,
1388
- "type": "option"
1389
- },
1390
- "fail-fast": {
1391
- "description": "Stop on first validation error",
1392
- "name": "fail-fast",
1393
- "allowNo": false,
1344
+ "follow": {
1345
+ "char": "f",
1346
+ "description": "Follow log output",
1347
+ "name": "follow",
1348
+ "allowNo": true,
1394
1349
  "type": "boolean"
1395
1350
  }
1396
1351
  },
1397
1352
  "hasDynamicHelp": false,
1398
1353
  "hiddenAliases": [],
1399
- "id": "secrets:validate",
1354
+ "id": "logs",
1400
1355
  "pluginAlias": "@enspirit/emb",
1401
1356
  "pluginName": "@enspirit/emb",
1402
1357
  "pluginType": "core",
1403
- "strict": true,
1404
- "enableJsonFlag": true,
1358
+ "strict": false,
1359
+ "enableJsonFlag": false,
1405
1360
  "isESM": true,
1406
1361
  "relativePath": [
1407
1362
  "dist",
1408
1363
  "src",
1409
1364
  "cli",
1410
1365
  "commands",
1411
- "secrets",
1412
- "validate.js"
1366
+ "logs",
1367
+ "index.js"
1413
1368
  ]
1414
1369
  },
1415
1370
  "resources:build": {
@@ -1667,7 +1622,184 @@
1667
1622
  "tasks",
1668
1623
  "run.js"
1669
1624
  ]
1625
+ },
1626
+ "secrets": {
1627
+ "aliases": [],
1628
+ "args": {},
1629
+ "description": "List all secret references in the configuration.",
1630
+ "examples": [
1631
+ "<%= config.bin %> <%= command.id %>",
1632
+ "<%= config.bin %> <%= command.id %> --json"
1633
+ ],
1634
+ "flags": {
1635
+ "json": {
1636
+ "description": "Format output as json.",
1637
+ "helpGroup": "GLOBAL",
1638
+ "name": "json",
1639
+ "allowNo": false,
1640
+ "type": "boolean"
1641
+ },
1642
+ "verbose": {
1643
+ "name": "verbose",
1644
+ "allowNo": true,
1645
+ "type": "boolean"
1646
+ },
1647
+ "root": {
1648
+ "char": "C",
1649
+ "description": "Run as if emb was started in <path>. Can also be set via EMB_ROOT env var.",
1650
+ "name": "root",
1651
+ "required": false,
1652
+ "hasDynamicHelp": false,
1653
+ "multiple": false,
1654
+ "type": "option"
1655
+ },
1656
+ "flavor": {
1657
+ "description": "Specify the flavor to use.",
1658
+ "name": "flavor",
1659
+ "required": false,
1660
+ "hasDynamicHelp": false,
1661
+ "multiple": false,
1662
+ "type": "option"
1663
+ }
1664
+ },
1665
+ "hasDynamicHelp": false,
1666
+ "hiddenAliases": [],
1667
+ "id": "secrets",
1668
+ "pluginAlias": "@enspirit/emb",
1669
+ "pluginName": "@enspirit/emb",
1670
+ "pluginType": "core",
1671
+ "strict": true,
1672
+ "enableJsonFlag": true,
1673
+ "isESM": true,
1674
+ "relativePath": [
1675
+ "dist",
1676
+ "src",
1677
+ "cli",
1678
+ "commands",
1679
+ "secrets",
1680
+ "index.js"
1681
+ ]
1682
+ },
1683
+ "secrets:providers": {
1684
+ "aliases": [],
1685
+ "args": {},
1686
+ "description": "Show configured secret providers and their status.",
1687
+ "examples": [
1688
+ "<%= config.bin %> <%= command.id %>"
1689
+ ],
1690
+ "flags": {
1691
+ "json": {
1692
+ "description": "Format output as json.",
1693
+ "helpGroup": "GLOBAL",
1694
+ "name": "json",
1695
+ "allowNo": false,
1696
+ "type": "boolean"
1697
+ },
1698
+ "verbose": {
1699
+ "name": "verbose",
1700
+ "allowNo": true,
1701
+ "type": "boolean"
1702
+ },
1703
+ "root": {
1704
+ "char": "C",
1705
+ "description": "Run as if emb was started in <path>. Can also be set via EMB_ROOT env var.",
1706
+ "name": "root",
1707
+ "required": false,
1708
+ "hasDynamicHelp": false,
1709
+ "multiple": false,
1710
+ "type": "option"
1711
+ },
1712
+ "flavor": {
1713
+ "description": "Specify the flavor to use.",
1714
+ "name": "flavor",
1715
+ "required": false,
1716
+ "hasDynamicHelp": false,
1717
+ "multiple": false,
1718
+ "type": "option"
1719
+ }
1720
+ },
1721
+ "hasDynamicHelp": false,
1722
+ "hiddenAliases": [],
1723
+ "id": "secrets:providers",
1724
+ "pluginAlias": "@enspirit/emb",
1725
+ "pluginName": "@enspirit/emb",
1726
+ "pluginType": "core",
1727
+ "strict": true,
1728
+ "enableJsonFlag": true,
1729
+ "isESM": true,
1730
+ "relativePath": [
1731
+ "dist",
1732
+ "src",
1733
+ "cli",
1734
+ "commands",
1735
+ "secrets",
1736
+ "providers.js"
1737
+ ]
1738
+ },
1739
+ "secrets:validate": {
1740
+ "aliases": [],
1741
+ "args": {},
1742
+ "description": "Validate that all secret references can be resolved (without showing values).",
1743
+ "examples": [
1744
+ "<%= config.bin %> <%= command.id %>",
1745
+ "<%= config.bin %> <%= command.id %> --fail-fast",
1746
+ "<%= config.bin %> <%= command.id %> --json"
1747
+ ],
1748
+ "flags": {
1749
+ "json": {
1750
+ "description": "Format output as json.",
1751
+ "helpGroup": "GLOBAL",
1752
+ "name": "json",
1753
+ "allowNo": false,
1754
+ "type": "boolean"
1755
+ },
1756
+ "verbose": {
1757
+ "name": "verbose",
1758
+ "allowNo": true,
1759
+ "type": "boolean"
1760
+ },
1761
+ "root": {
1762
+ "char": "C",
1763
+ "description": "Run as if emb was started in <path>. Can also be set via EMB_ROOT env var.",
1764
+ "name": "root",
1765
+ "required": false,
1766
+ "hasDynamicHelp": false,
1767
+ "multiple": false,
1768
+ "type": "option"
1769
+ },
1770
+ "flavor": {
1771
+ "description": "Specify the flavor to use.",
1772
+ "name": "flavor",
1773
+ "required": false,
1774
+ "hasDynamicHelp": false,
1775
+ "multiple": false,
1776
+ "type": "option"
1777
+ },
1778
+ "fail-fast": {
1779
+ "description": "Stop on first validation error",
1780
+ "name": "fail-fast",
1781
+ "allowNo": false,
1782
+ "type": "boolean"
1783
+ }
1784
+ },
1785
+ "hasDynamicHelp": false,
1786
+ "hiddenAliases": [],
1787
+ "id": "secrets:validate",
1788
+ "pluginAlias": "@enspirit/emb",
1789
+ "pluginName": "@enspirit/emb",
1790
+ "pluginType": "core",
1791
+ "strict": true,
1792
+ "enableJsonFlag": true,
1793
+ "isESM": true,
1794
+ "relativePath": [
1795
+ "dist",
1796
+ "src",
1797
+ "cli",
1798
+ "commands",
1799
+ "secrets",
1800
+ "validate.js"
1801
+ ]
1670
1802
  }
1671
1803
  },
1672
- "version": "0.17.5"
1804
+ "version": "0.18.0"
1673
1805
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@enspirit/emb",
3
3
  "type": "module",
4
- "version": "0.17.5",
4
+ "version": "0.18.0",
5
5
  "keywords": [
6
6
  "monorepo",
7
7
  "docker",