From 2c0a427ba57b9f4b9f13b6baed011e651467fe7e Mon Sep 17 00:00:00 2001
From: Joseph Garrone <joseph.garrone.gj@gmail.com>
Date: Mon, 10 Jun 2024 20:51:00 +0200
Subject: [PATCH] Fix the script to export realm

---
 scripts/dump-keycloak-realm.ts | 101 +++++++++++++++++++++++----------
 1 file changed, 72 insertions(+), 29 deletions(-)

diff --git a/scripts/dump-keycloak-realm.ts b/scripts/dump-keycloak-realm.ts
index c50269c9..da5877eb 100644
--- a/scripts/dump-keycloak-realm.ts
+++ b/scripts/dump-keycloak-realm.ts
@@ -3,40 +3,83 @@ import child_process from "child_process";
 import { SemVer } from "../src/bin/tools/SemVer";
 import { join as pathJoin, relative as pathRelative } from "path";
 import chalk from "chalk";
+import { Deferred } from "evt/tools/Deferred";
+import { assert } from "tsafe/assert";
+import { is } from "tsafe/is";
 
-run(
-    [
-        `docker exec -it ${containerName}`,
-        `/opt/keycloak/bin/kc.sh export`,
-        `--dir /tmp`,
-        `--realm myrealm`,
-        `--users realm_file`
-    ].join(" ")
-);
+(async () => {
+    {
+        const dCompleted = new Deferred<void>();
 
-const keycloakMajorVersionNumber = SemVer.parse(
-    child_process
-        .execSync(`docker inspect --format '{{.Config.Image}}' ${containerName}`)
-        .toString("utf8")
-        .trim()
-        .split(":")[1]
-).major;
+        const child = child_process.spawn("docker", [
+            ...["exec", containerName],
+            ...["/opt/keycloak/bin/kc.sh", "export"],
+            ...["--dir", "/tmp"],
+            ...["--realm", "myrealm"],
+            ...["--users", "realm_file"]
+        ]);
 
-const targetFilePath = pathRelative(
-    process.cwd(),
-    pathJoin(
-        __dirname,
-        "..",
-        "src",
-        "bin",
-        "start-keycloak",
-        `myrealm-realm-${keycloakMajorVersionNumber}.json`
-    )
-);
+        let output = "";
 
-run(`docker cp ${containerName}:/tmp/myrealm-realm.json ${targetFilePath}`);
+        const onExit = (code: number | null) => {
+            dCompleted.reject(new Error(`Exited with code ${code}`));
+        };
 
-console.log(`${chalk.green(`✓ Exported realm to`)} ${chalk.bold(targetFilePath)}`);
+        child.on("exit", onExit);
+
+        child.stdout.on("data", data => {
+            const outputStr = data.toString("utf8");
+
+            if (outputStr.includes("Export finished successfully")) {
+                child.removeListener("exit", onExit);
+
+                child.kill();
+
+                dCompleted.resolve();
+            }
+
+            output += outputStr;
+        });
+
+        child.stderr.on("data", data => (output += chalk.red(data.toString("utf8"))));
+
+        try {
+            await dCompleted.pr;
+        } catch (error) {
+            assert(is<Error>(error));
+
+            console.log(chalk.red(error.message));
+
+            console.log(output);
+
+            process.exit(1);
+        }
+    }
+
+    const keycloakMajorVersionNumber = SemVer.parse(
+        child_process
+            .execSync(`docker inspect --format '{{.Config.Image}}' ${containerName}`)
+            .toString("utf8")
+            .trim()
+            .split(":")[1]
+    ).major;
+
+    const targetFilePath = pathRelative(
+        process.cwd(),
+        pathJoin(
+            __dirname,
+            "..",
+            "src",
+            "bin",
+            "start-keycloak",
+            `myrealm-realm-${keycloakMajorVersionNumber}.json`
+        )
+    );
+
+    run(`docker cp ${containerName}:/tmp/myrealm-realm.json ${targetFilePath}`);
+
+    console.log(`${chalk.green(`✓ Exported realm to`)} ${chalk.bold(targetFilePath)}`);
+})();
 
 function run(command: string) {
     console.log(chalk.grey(`$ ${command}`));