@forge/cli-shared
9.4.1-next.39.4.1-next.3-experimental-e9e08bb
out/tunnel/compose-project-lifecycle.js+
out/tunnel/compose-project-lifecycle.jsNew file+105
Index: package/out/tunnel/compose-project-lifecycle.js
===================================================================
--- package/out/tunnel/compose-project-lifecycle.js
+++ package/out/tunnel/compose-project-lifecycle.js
@@ -0,0 +1,105 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.parseComposePs = exports.ComposeProjectLifecycle = void 0;
+const tslib_1 = require("tslib");
+const path = tslib_1.__importStar(require("path"));
+const docker_compose_1 = require("docker-compose");
+const docker_compose_lifecycle_1 = require("./docker-compose-lifecycle");
+const defaultAdapter = {
+ pullOne: (service, options) => (0, docker_compose_1.pullOne)(service, options),
+ exec: (command, args, options) => (0, docker_compose_1.execCompose)(command, args, options),
+ down: (options) => (0, docker_compose_1.downAll)(options)
+};
+class ComposeProjectLifecycle {
+ configPath;
+ projectName;
+ logger;
+ adapter;
+ constructor(configPath, projectName, logger, adapter = defaultAdapter) {
+ this.configPath = configPath;
+ this.projectName = projectName;
+ this.logger = logger;
+ this.adapter = adapter;
+ }
+ options(log = false) {
+ return {
+ cwd: path.dirname(this.configPath),
+ log,
+ config: this.configPath,
+ composeOptions: [`-p${this.projectName}`],
+ callback: (0, docker_compose_lifecycle_1.createDockerLifecycleLogFilter)(this.logger)
+ };
+ }
+ async pull(services) {
+ for (const service of services) {
+ try {
+ await this.adapter.pullOne(service, this.options());
+ }
+ catch (error) {
+ throw new Error(`Unable to pull the ${service} image: ${(0, docker_compose_lifecycle_1.getDockerComposeErrorMessage)(error)}`);
+ }
+ }
+ }
+ async up(services) {
+ try {
+ await this.adapter.exec('up', ['--detach', '--no-build', '--remove-orphans', ...services], this.options());
+ }
+ catch (error) {
+ throw new Error(`Unable to start the Docker Compose project: ${(0, docker_compose_lifecycle_1.getDockerComposeErrorMessage)(error)}`);
+ }
+ }
+ async down() {
+ try {
+ await this.adapter.down(this.options());
+ }
+ catch (error) {
+ throw new Error(`Unable to stop the Docker Compose project: ${(0, docker_compose_lifecycle_1.getDockerComposeErrorMessage)(error)}`);
+ }
+ }
+ async states() {
+ try {
+ const result = await this.adapter.exec('ps', ['--all', '--format', 'json'], this.options());
+ return (0, exports.parseComposePs)(result.out ?? '');
+ }
+ catch (error) {
+ throw new Error(`Unable to inspect the Docker Compose project: ${(0, docker_compose_lifecycle_1.getDockerComposeErrorMessage)(error)}`);
+ }
+ }
+ async logs(service, lines = 80) {
+ try {
+ const result = await this.adapter.exec('logs', ['--no-color', '--tail', lines.toString(), service], this.options());
+ return [result.out, result.err].filter(Boolean).join('\n').trim();
+ }
+ catch (error) {
+ return (0, docker_compose_lifecycle_1.getDockerComposeErrorMessage)(error);
+ }
+ }
+}
+exports.ComposeProjectLifecycle = ComposeProjectLifecycle;
+const parseComposePs = (output) => {
+ const trimmed = output.trim();
+ if (!trimmed)
+ return [];
+ const records = (() => {
+ try {
+ const parsed = JSON.parse(trimmed);
+ return Array.isArray(parsed) ? parsed : [parsed];
+ }
+ catch {
+ return trimmed
+ .split('\n')
+ .filter(Boolean)
+ .map((line) => JSON.parse(line));
+ }
+ })();
+ return records.map((item) => {
+ const value = item;
+ return {
+ name: String(value.Name ?? value.name ?? ''),
+ service: String(value.Service ?? value.service ?? ''),
+ state: String(value.State ?? value.state ?? ''),
+ health: value.Health == null && value.health == null ? undefined : String(value.Health ?? value.health)
+ };
+ });
+};
+exports.parseComposePs = parseComposePs;