@quatrain/app 1.1.8 → 1.1.10

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/dist/Infra.d.ts CHANGED
@@ -5,7 +5,8 @@ export declare class AppInfra {
5
5
  message: string;
6
6
  }) => void): Promise<void>;
7
7
  static stop(config: Record<string, any>): Promise<void>;
8
- private static getComposeCommand;
8
+ private static getPodmanCommand;
9
+ private static getDockerCommand;
9
10
  private static runCompose;
10
11
  }
11
12
  //# sourceMappingURL=Infra.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Infra.d.ts","sourceRoot":"","sources":["../src/Infra.ts"],"names":[],"mappings":"AAOA,qBAAa,QAAQ;WAME,KAAK,CACtB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,GACxG,OAAO,CAAC,IAAI,CAAC;WAuCI,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAYpE,OAAO,CAAC,MAAM,CAAC,iBAAiB;mBAKX,UAAU;CAmDjC"}
1
+ {"version":3,"file":"Infra.d.ts","sourceRoot":"","sources":["../src/Infra.ts"],"names":[],"mappings":"AAQA,qBAAa,QAAQ;WAME,KAAK,CACtB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,GACxG,OAAO,CAAC,IAAI,CAAC;WAuCI,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;mBAY/C,gBAAgB;mBAShB,gBAAgB;mBAShB,UAAU;CAsDjC"}
package/dist/Infra.js CHANGED
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.AppInfra = void 0;
7
7
  const child_process_1 = require("child_process");
8
+ const core_1 = require("@quatrain/core");
8
9
  const path_1 = __importDefault(require("path"));
9
10
  const log_1 = require("@quatrain/log");
10
11
  const fs_1 = __importDefault(require("fs"));
@@ -50,55 +51,71 @@ class AppInfra {
50
51
  log_1.Log.error(`[Infra] Failed to stop infrastructure: ${e.message}`);
51
52
  }
52
53
  }
53
- static getComposeCommand() {
54
- return 'podman compose';
54
+ static async getPodmanCommand() {
55
+ const cmd = process.env.PODMAN_BIN_PATH || 'podman';
56
+ try {
57
+ return await core_1.Core.getSystemCommandPath(cmd);
58
+ }
59
+ catch (e) {
60
+ return cmd;
61
+ }
62
+ }
63
+ static async getDockerCommand() {
64
+ const cmd = process.env.DOCKER_BIN_PATH || 'docker';
65
+ try {
66
+ return await core_1.Core.getSystemCommandPath(cmd);
67
+ }
68
+ catch (e) {
69
+ return cmd;
70
+ }
55
71
  }
56
72
  static async runCompose(action, composeFile, onProgress) {
73
+ if (!fs_1.default.existsSync(composeFile)) {
74
+ log_1.Log.error(`[Infra] Compose file not found at: ${composeFile}`);
75
+ throw new Error(`Compose file not found: ${composeFile}`);
76
+ }
77
+ const args = ['compose', '-f', composeFile, ...action.split(' ')];
78
+ const podmanCmd = await this.getPodmanCommand();
79
+ log_1.Log.info(`[Infra] Executing: ${podmanCmd} ${args.join(' ')}`);
57
80
  return new Promise((resolve, reject) => {
58
- if (!fs_1.default.existsSync(composeFile)) {
59
- log_1.Log.error(`[Infra] Compose file not found at: ${composeFile}`);
60
- return reject(new Error(`Compose file not found: ${composeFile}`));
61
- }
62
- const cmd = `${this.getComposeCommand()} -f ${composeFile} ${action}`;
63
- log_1.Log.info(`[Infra] Executing: ${cmd}`);
64
- const child = (0, child_process_1.exec)(cmd, (error, stdout, stderr) => {
65
- if (error) {
66
- if (error.message.includes('command not found')) {
67
- log_1.Log.warn(`[Infra] podman compose not found, falling back to docker compose...`);
68
- (0, child_process_1.exec)(`docker compose -f ${composeFile} ${action}`, (err2, out2, errOut2) => {
69
- if (err2) {
70
- log_1.Log.error(`[Infra] Failed to run infrastructure: ${err2.message}`);
71
- return reject(err2);
72
- }
73
- if (out2)
74
- log_1.Log.debug(`[Infra] ${out2}`);
75
- if (errOut2)
76
- log_1.Log.debug(`[Infra] ${errOut2}`);
77
- resolve();
78
- });
79
- return;
81
+ const child = (0, child_process_1.spawn)(podmanCmd, args, { shell: false });
82
+ const handleChild = (proc, isFallback) => {
83
+ proc.on('error', (error) => {
84
+ if (!isFallback && error.code === 'ENOENT') {
85
+ log_1.Log.warn(`[Infra] podman not found, falling back to docker...`);
86
+ this.getDockerCommand().then(dockerCmd => {
87
+ const fallbackChild = (0, child_process_1.spawn)(dockerCmd, args, { shell: false });
88
+ handleChild(fallbackChild, true);
89
+ }).catch(reject);
90
+ }
91
+ else {
92
+ log_1.Log.error(`[Infra] Failed to run infrastructure: ${error.message}`);
93
+ reject(error);
80
94
  }
81
- log_1.Log.error(`[Infra] Failed to run infrastructure: ${error.message}`);
82
- return reject(error);
83
- }
84
- if (stdout)
85
- log_1.Log.debug(`[Infra] ${stdout}`);
86
- if (stderr)
87
- log_1.Log.debug(`[Infra] ${stderr}`);
88
- resolve();
89
- });
90
- if (child.stdout) {
91
- child.stdout.on('data', (data) => {
92
- const text = data.toString().trim();
93
- console.log(text);
94
95
  });
95
- }
96
- if (child.stderr) {
97
- child.stderr.on('data', (data) => {
98
- const text = data.toString().trim();
99
- console.error(text);
96
+ proc.on('close', (code) => {
97
+ if (code !== 0) {
98
+ log_1.Log.error(`[Infra] Command failed with exit code ${code}`);
99
+ return reject(new Error(`Command failed with exit code ${code}`));
100
+ }
101
+ resolve();
100
102
  });
101
- }
103
+ if (proc.stdout) {
104
+ proc.stdout.on('data', (data) => {
105
+ const text = data.toString().trim();
106
+ if (text)
107
+ console.log(text);
108
+ });
109
+ }
110
+ if (proc.stderr) {
111
+ proc.stderr.on('data', (data) => {
112
+ const text = data.toString().trim();
113
+ if (text)
114
+ console.error(text);
115
+ });
116
+ }
117
+ };
118
+ handleChild(child, false);
102
119
  });
103
120
  }
104
121
  }
package/dist/Infra.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Infra.js","sourceRoot":"","sources":["../src/Infra.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Infra.js","sourceRoot":"","sources":["../src/Infra.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quatrain/app",
3
- "version": "1.1.8",
3
+ "version": "1.1.10",
4
4
  "license": "AGPL-3.0-only",
5
5
  "description": "Quatrain App Bootloader and configuration helpers",
6
6
  "main": "dist/index.js",
@@ -21,8 +21,8 @@
21
21
  "author": "Quatrain Développement SAS <developers@quatrain.com>",
22
22
  "dependencies": {
23
23
  "@quatrain/auth": "^1.2.1",
24
- "@quatrain/backend": "^1.2.1",
25
- "@quatrain/core": "^1.2.2",
24
+ "@quatrain/backend": "^1.2.3",
25
+ "@quatrain/core": "^1.2.4",
26
26
  "@quatrain/log": "^1.2.1",
27
27
  "@quatrain/messaging": "^1.1.1",
28
28
  "@quatrain/queue": "^1.2.1",
package/src/Infra.ts CHANGED
@@ -1,4 +1,5 @@
1
- import { exec } from 'child_process'
1
+ import { spawn } from 'child_process'
2
+ import { Core } from '@quatrain/core'
2
3
  import path from 'path'
3
4
  import { Log } from '@quatrain/log'
4
5
  import fs from 'fs'
@@ -65,60 +66,76 @@ export class AppInfra {
65
66
  }
66
67
  }
67
68
 
68
- private static getComposeCommand(): string {
69
- // Prioritize podman compose if working 'modern', otherwise fallback to docker compose
70
- return 'podman compose'
69
+ private static async getPodmanCommand(): Promise<string> {
70
+ const cmd = process.env.PODMAN_BIN_PATH || 'podman'
71
+ try {
72
+ return await Core.getSystemCommandPath(cmd)
73
+ } catch (e) {
74
+ return cmd
75
+ }
76
+ }
77
+
78
+ private static async getDockerCommand(): Promise<string> {
79
+ const cmd = process.env.DOCKER_BIN_PATH || 'docker'
80
+ try {
81
+ return await Core.getSystemCommandPath(cmd)
82
+ } catch (e) {
83
+ return cmd
84
+ }
71
85
  }
72
86
 
73
87
  private static async runCompose(action: string, composeFile: string, onProgress?: (event: { step: string; status: 'running' | 'success' | 'error'; message: string }) => void): Promise<void> {
88
+ if (!fs.existsSync(composeFile)) {
89
+ Log.error(`[Infra] Compose file not found at: ${composeFile}`)
90
+ throw new Error(`Compose file not found: ${composeFile}`)
91
+ }
92
+
93
+ const args = ['compose', '-f', composeFile, ...action.split(' ')]
94
+ const podmanCmd = await this.getPodmanCommand()
95
+ Log.info(`[Infra] Executing: ${podmanCmd} ${args.join(' ')}`)
96
+
74
97
  return new Promise((resolve, reject) => {
75
- if (!fs.existsSync(composeFile)) {
76
- Log.error(`[Infra] Compose file not found at: ${composeFile}`)
77
- return reject(new Error(`Compose file not found: ${composeFile}`))
78
- }
98
+ const child = spawn(podmanCmd, args, { shell: false })
79
99
 
80
- const cmd = `${this.getComposeCommand()} -f ${composeFile} ${action}`
81
- Log.info(`[Infra] Executing: ${cmd}`)
82
-
83
- const child = exec(cmd, (error, stdout, stderr) => {
84
- if (error) {
85
- // Fallback to docker-compose if podman-compose is not installed
86
- if (error.message.includes('command not found')) {
87
- Log.warn(`[Infra] podman compose not found, falling back to docker compose...`)
88
- exec(`docker compose -f ${composeFile} ${action}`, (err2, out2, errOut2) => {
89
- if (err2) {
90
- Log.error(`[Infra] Failed to run infrastructure: ${err2.message}`)
91
- return reject(err2)
92
- }
93
- if (out2) Log.debug(`[Infra] ${out2}`)
94
- if (errOut2) Log.debug(`[Infra] ${errOut2}`)
95
- resolve()
96
- })
97
- return
100
+ const handleChild = (proc: ReturnType<typeof spawn>, isFallback: boolean) => {
101
+ proc.on('error', (error: any) => {
102
+ // Fallback to docker if podman is not installed
103
+ if (!isFallback && error.code === 'ENOENT') {
104
+ Log.warn(`[Infra] podman not found, falling back to docker...`)
105
+ this.getDockerCommand().then(dockerCmd => {
106
+ const fallbackChild = spawn(dockerCmd, args, { shell: false })
107
+ handleChild(fallbackChild, true)
108
+ }).catch(reject)
109
+ } else {
110
+ Log.error(`[Infra] Failed to run infrastructure: ${error.message}`)
111
+ reject(error)
98
112
  }
99
- Log.error(`[Infra] Failed to run infrastructure: ${error.message}`)
100
- return reject(error)
101
- }
102
- if (stdout) Log.debug(`[Infra] ${stdout}`)
103
- if (stderr) Log.debug(`[Infra] ${stderr}`)
104
- resolve()
105
- })
106
-
107
- // Stream output to console and emit progress events
108
- if (child.stdout) {
109
- child.stdout.on('data', (data) => {
110
- const text = data.toString().trim()
111
- console.log(text)
112
- // Could emit sub-steps here if desired:
113
- // onProgress?.({ step: 'compose', status: 'running', message: text })
114
113
  })
115
- }
116
- if (child.stderr) {
117
- child.stderr.on('data', (data) => {
118
- const text = data.toString().trim()
119
- console.error(text)
114
+
115
+ proc.on('close', (code) => {
116
+ if (code !== 0) {
117
+ Log.error(`[Infra] Command failed with exit code ${code}`)
118
+ return reject(new Error(`Command failed with exit code ${code}`))
119
+ }
120
+ resolve()
120
121
  })
122
+
123
+ // Stream output to console
124
+ if (proc.stdout) {
125
+ proc.stdout.on('data', (data) => {
126
+ const text = data.toString().trim()
127
+ if (text) console.log(text)
128
+ })
129
+ }
130
+ if (proc.stderr) {
131
+ proc.stderr.on('data', (data) => {
132
+ const text = data.toString().trim()
133
+ if (text) console.error(text)
134
+ })
135
+ }
121
136
  }
137
+
138
+ handleChild(child, false)
122
139
  })
123
140
  }
124
141
  }