@companyhelm/cli 0.1.2 → 0.1.4
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/LICENSE +21 -0
- package/README.md +40 -33
- package/dist/cli.js +11 -1
- package/dist/commands/dependencies.d.ts +18 -3
- package/dist/commands/dependencies.js +76 -13
- package/dist/commands/interactive.d.ts +6 -0
- package/dist/commands/interactive.js +22 -0
- package/dist/commands/logs.js +6 -1
- package/dist/commands/register-commands.js +4 -0
- package/dist/commands/reset.d.ts +4 -0
- package/dist/commands/reset.js +43 -4
- package/dist/commands/set-image-version.d.ts +31 -0
- package/dist/commands/set-image-version.js +87 -0
- package/dist/commands/setup-github-app.d.ts +10 -0
- package/dist/commands/setup-github-app.js +211 -0
- package/dist/commands/status.js +3 -1
- package/dist/commands/up.js +11 -2
- package/dist/core/bootstrap/DeploymentBootstrapper.d.ts +2 -2
- package/dist/core/bootstrap/DeploymentBootstrapper.js +5 -7
- package/dist/core/bootstrap/SeedSqlRenderer.js +23 -5
- package/dist/core/config/ApiEnvFileWriter.d.ts +6 -0
- package/dist/core/config/ApiEnvFileWriter.js +26 -0
- package/dist/core/config/GithubAppConfig.d.ts +6 -0
- package/dist/core/config/GithubAppConfig.js +26 -0
- package/dist/core/config/GithubAppConfigStore.d.ts +11 -0
- package/dist/core/config/GithubAppConfigStore.js +65 -0
- package/dist/core/docker/ComposeTemplateRenderer.d.ts +6 -1
- package/dist/core/docker/ComposeTemplateRenderer.js +22 -4
- package/dist/core/docker/DockerStackManager.d.ts +15 -3
- package/dist/core/docker/DockerStackManager.js +67 -8
- package/dist/core/runner/RunnerSupervisor.d.ts +4 -0
- package/dist/core/runner/RunnerSupervisor.js +19 -3
- package/dist/core/runtime/ImageCatalog.js +5 -2
- package/dist/core/runtime/LocalConfigStore.d.ts +16 -0
- package/dist/core/runtime/LocalConfigStore.js +59 -0
- package/dist/core/runtime/ManagedImages.d.ts +10 -0
- package/dist/core/runtime/ManagedImages.js +27 -0
- package/dist/core/runtime/ProjectPaths.d.ts +7 -0
- package/dist/core/runtime/ProjectPaths.js +16 -0
- package/dist/core/runtime/PublicImageTagRegistry.d.ts +16 -0
- package/dist/core/runtime/PublicImageTagRegistry.js +148 -0
- package/dist/core/runtime/RuntimeState.d.ts +1 -1
- package/dist/core/runtime/RuntimeStateStore.d.ts +1 -0
- package/dist/core/runtime/RuntimeStateStore.js +8 -2
- package/dist/core/runtime/VersionCatalog.d.ts +10 -0
- package/dist/core/runtime/VersionCatalog.js +21 -0
- package/dist/core/status/StatusService.d.ts +5 -1
- package/dist/core/status/StatusService.js +5 -2
- package/dist/core/ui/TerminalRenderer.d.ts +10 -0
- package/dist/core/ui/TerminalRenderer.js +48 -0
- package/dist/templates/docker-compose.yaml.tpl +4 -13
- package/dist/templates/seed.sql.tpl +32 -13
- package/package.json +7 -3
- package/src/templates/docker-compose.yaml.tpl +4 -13
- package/src/templates/seed.sql.tpl +32 -13
|
@@ -2,6 +2,8 @@ import chalk from "chalk";
|
|
|
2
2
|
import figlet from "figlet";
|
|
3
3
|
export class TerminalRenderer {
|
|
4
4
|
useColor;
|
|
5
|
+
static OSC = "\u001B]";
|
|
6
|
+
static BEL = "\u0007";
|
|
5
7
|
constructor(useColor = true) {
|
|
6
8
|
this.useColor = useColor;
|
|
7
9
|
}
|
|
@@ -14,6 +16,52 @@ export class TerminalRenderer {
|
|
|
14
16
|
success(message) {
|
|
15
17
|
return `${this.colorize("[ok]", "green")} ${message}`;
|
|
16
18
|
}
|
|
19
|
+
progress(message) {
|
|
20
|
+
return this.colorize(`... ${message}`, "cyan");
|
|
21
|
+
}
|
|
22
|
+
successHighlight(message) {
|
|
23
|
+
if (!this.useColor) {
|
|
24
|
+
return message;
|
|
25
|
+
}
|
|
26
|
+
return chalk.green.bold(message);
|
|
27
|
+
}
|
|
28
|
+
clickableUrl(url) {
|
|
29
|
+
if (!this.useColor) {
|
|
30
|
+
return url;
|
|
31
|
+
}
|
|
32
|
+
const display = this.successHighlight(url);
|
|
33
|
+
return `${TerminalRenderer.OSC}8;;${url}${TerminalRenderer.BEL}${display}${TerminalRenderer.OSC}8;;${TerminalRenderer.BEL}`;
|
|
34
|
+
}
|
|
35
|
+
renderStatus(report) {
|
|
36
|
+
const lines = ["Status"];
|
|
37
|
+
lines.push(this.renderServiceLine("Postgres", report.services.postgres));
|
|
38
|
+
lines.push(this.renderServiceLine("API", report.services.api, report.apiUrl));
|
|
39
|
+
lines.push(this.renderServiceLine("Frontend", report.services.frontend, report.uiUrl));
|
|
40
|
+
lines.push(this.renderServiceLine("Runner", report.services.runner));
|
|
41
|
+
if (report.versions) {
|
|
42
|
+
lines.push(`CompanyHelm CLI: ${report.versions.cliPackage}`);
|
|
43
|
+
lines.push(`Runner package: ${report.versions.runnerPackage}`);
|
|
44
|
+
lines.push(`API image: ${report.versions.images.api}`);
|
|
45
|
+
lines.push(`Frontend image: ${report.versions.images.frontend}`);
|
|
46
|
+
lines.push(`Postgres image: ${report.versions.images.postgres}`);
|
|
47
|
+
}
|
|
48
|
+
if (report.username) {
|
|
49
|
+
lines.push(`username: ${report.username}`);
|
|
50
|
+
}
|
|
51
|
+
return lines.join("\n");
|
|
52
|
+
}
|
|
53
|
+
renderServiceLine(label, status, detail) {
|
|
54
|
+
const statusLabel = status === "running" ? this.success("running") : this.warn("stopped");
|
|
55
|
+
return detail && status === "running"
|
|
56
|
+
? `${label}: ${statusLabel} (${this.formatDetail(detail)})`
|
|
57
|
+
: `${label}: ${statusLabel}`;
|
|
58
|
+
}
|
|
59
|
+
warn(message) {
|
|
60
|
+
return `${this.colorize("[!]", "yellow")} ${message}`;
|
|
61
|
+
}
|
|
62
|
+
formatDetail(detail) {
|
|
63
|
+
return detail.startsWith("http://") || detail.startsWith("https://") ? this.clickableUrl(detail) : detail;
|
|
64
|
+
}
|
|
17
65
|
colorize(text, color) {
|
|
18
66
|
if (!this.useColor) {
|
|
19
67
|
return text;
|
|
@@ -13,8 +13,11 @@ services:
|
|
|
13
13
|
|
|
14
14
|
api:
|
|
15
15
|
image: {{API_IMAGE}}
|
|
16
|
+
platform: linux/amd64
|
|
16
17
|
depends_on:
|
|
17
18
|
- postgres
|
|
19
|
+
env_file:
|
|
20
|
+
- "{{API_ENV_PATH}}"
|
|
18
21
|
environment:
|
|
19
22
|
COMPANYHELM_CONFIG_PATH: /run/companyhelm/config.yaml
|
|
20
23
|
ports:
|
|
@@ -26,19 +29,7 @@ services:
|
|
|
26
29
|
networks:
|
|
27
30
|
- companyhelm
|
|
28
31
|
|
|
29
|
-
|
|
30
|
-
image: {{FRONTEND_IMAGE}}
|
|
31
|
-
depends_on:
|
|
32
|
-
- api
|
|
33
|
-
environment:
|
|
34
|
-
COMPANYHELM_CONFIG_PATH: /run/companyhelm/config.yaml
|
|
35
|
-
PORT: "{{UI_PORT}}"
|
|
36
|
-
ports:
|
|
37
|
-
- "{{UI_PORT}}:{{UI_PORT}}"
|
|
38
|
-
volumes:
|
|
39
|
-
- "{{FRONTEND_CONFIG_PATH}}:/run/companyhelm/config.yaml:ro"
|
|
40
|
-
networks:
|
|
41
|
-
- companyhelm
|
|
32
|
+
{{FRONTEND_SERVICE_BLOCK}}
|
|
42
33
|
|
|
43
34
|
networks:
|
|
44
35
|
companyhelm:
|
|
@@ -5,8 +5,17 @@ VALUES ('{{COMPANY_ID}}', '{{COMPANY_NAME}}')
|
|
|
5
5
|
ON CONFLICT (id) DO UPDATE
|
|
6
6
|
SET name = EXCLUDED.name;
|
|
7
7
|
|
|
8
|
+
UPDATE users
|
|
9
|
+
SET first_name = '{{USER_FIRST_NAME}}',
|
|
10
|
+
last_name = NULL,
|
|
11
|
+
email = '{{USER_EMAIL}}',
|
|
12
|
+
auth_provider = 'companyhelm',
|
|
13
|
+
updated_at = NOW()
|
|
14
|
+
WHERE id = '{{USER_ID}}'
|
|
15
|
+
OR email = '{{USER_EMAIL}}';
|
|
16
|
+
|
|
8
17
|
INSERT INTO users (id, first_name, last_name, email, auth_provider, created_at, updated_at)
|
|
9
|
-
|
|
18
|
+
SELECT
|
|
10
19
|
'{{USER_ID}}',
|
|
11
20
|
'{{USER_FIRST_NAME}}',
|
|
12
21
|
NULL,
|
|
@@ -14,14 +23,24 @@ VALUES (
|
|
|
14
23
|
'companyhelm',
|
|
15
24
|
NOW(),
|
|
16
25
|
NOW()
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
26
|
+
WHERE NOT EXISTS (
|
|
27
|
+
SELECT 1
|
|
28
|
+
FROM users
|
|
29
|
+
WHERE id = '{{USER_ID}}'
|
|
30
|
+
OR email = '{{USER_EMAIL}}'
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
UPDATE user_auths
|
|
34
|
+
SET user_id = '{{USER_ID}}',
|
|
35
|
+
email = '{{USER_EMAIL}}',
|
|
36
|
+
password_salt = '{{PASSWORD_SALT}}',
|
|
37
|
+
password_hash = '{{PASSWORD_HASH}}',
|
|
38
|
+
updated_at = NOW()
|
|
39
|
+
WHERE user_id = '{{USER_ID}}'
|
|
40
|
+
OR email = '{{USER_EMAIL}}';
|
|
22
41
|
|
|
23
42
|
INSERT INTO user_auths (id, user_id, email, password_salt, password_hash, created_at, updated_at)
|
|
24
|
-
|
|
43
|
+
SELECT
|
|
25
44
|
'{{USER_AUTH_ID}}',
|
|
26
45
|
'{{USER_ID}}',
|
|
27
46
|
'{{USER_EMAIL}}',
|
|
@@ -29,12 +48,12 @@ VALUES (
|
|
|
29
48
|
'{{PASSWORD_HASH}}',
|
|
30
49
|
NOW(),
|
|
31
50
|
NOW()
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
51
|
+
WHERE NOT EXISTS (
|
|
52
|
+
SELECT 1
|
|
53
|
+
FROM user_auths
|
|
54
|
+
WHERE user_id = '{{USER_ID}}'
|
|
55
|
+
OR email = '{{USER_EMAIL}}'
|
|
56
|
+
);
|
|
38
57
|
|
|
39
58
|
INSERT INTO company_members (company_id, user_id)
|
|
40
59
|
VALUES ('{{COMPANY_ID}}', '{{USER_ID}}')
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@companyhelm/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "Bootstrap and manage a local CompanyHelm deployment.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"private": false,
|
|
@@ -21,14 +21,18 @@
|
|
|
21
21
|
],
|
|
22
22
|
"scripts": {
|
|
23
23
|
"build": "tsc -p tsconfig.json && node scripts/copy-templates.cjs",
|
|
24
|
+
"set-image-version": "npm run build && node dist/cli.js set-image-version",
|
|
25
|
+
"start": "npm run build && node dist/cli.js",
|
|
24
26
|
"test": "npm run build && vitest run"
|
|
25
27
|
},
|
|
26
28
|
"dependencies": {
|
|
27
|
-
"@
|
|
29
|
+
"@clack/prompts": "^1.1.0",
|
|
30
|
+
"@companyhelm/runner": "^0.1.1",
|
|
28
31
|
"chalk": "^5.6.2",
|
|
29
32
|
"commander": "^14.0.1",
|
|
30
33
|
"dockerode": "^4.0.9",
|
|
31
|
-
"figlet": "^1.9.4"
|
|
34
|
+
"figlet": "^1.9.4",
|
|
35
|
+
"yaml": "^2.8.1"
|
|
32
36
|
},
|
|
33
37
|
"devDependencies": {
|
|
34
38
|
"@types/dockerode": "^3.3.44",
|
|
@@ -13,8 +13,11 @@ services:
|
|
|
13
13
|
|
|
14
14
|
api:
|
|
15
15
|
image: {{API_IMAGE}}
|
|
16
|
+
platform: linux/amd64
|
|
16
17
|
depends_on:
|
|
17
18
|
- postgres
|
|
19
|
+
env_file:
|
|
20
|
+
- "{{API_ENV_PATH}}"
|
|
18
21
|
environment:
|
|
19
22
|
COMPANYHELM_CONFIG_PATH: /run/companyhelm/config.yaml
|
|
20
23
|
ports:
|
|
@@ -26,19 +29,7 @@ services:
|
|
|
26
29
|
networks:
|
|
27
30
|
- companyhelm
|
|
28
31
|
|
|
29
|
-
|
|
30
|
-
image: {{FRONTEND_IMAGE}}
|
|
31
|
-
depends_on:
|
|
32
|
-
- api
|
|
33
|
-
environment:
|
|
34
|
-
COMPANYHELM_CONFIG_PATH: /run/companyhelm/config.yaml
|
|
35
|
-
PORT: "{{UI_PORT}}"
|
|
36
|
-
ports:
|
|
37
|
-
- "{{UI_PORT}}:{{UI_PORT}}"
|
|
38
|
-
volumes:
|
|
39
|
-
- "{{FRONTEND_CONFIG_PATH}}:/run/companyhelm/config.yaml:ro"
|
|
40
|
-
networks:
|
|
41
|
-
- companyhelm
|
|
32
|
+
{{FRONTEND_SERVICE_BLOCK}}
|
|
42
33
|
|
|
43
34
|
networks:
|
|
44
35
|
companyhelm:
|
|
@@ -5,8 +5,17 @@ VALUES ('{{COMPANY_ID}}', '{{COMPANY_NAME}}')
|
|
|
5
5
|
ON CONFLICT (id) DO UPDATE
|
|
6
6
|
SET name = EXCLUDED.name;
|
|
7
7
|
|
|
8
|
+
UPDATE users
|
|
9
|
+
SET first_name = '{{USER_FIRST_NAME}}',
|
|
10
|
+
last_name = NULL,
|
|
11
|
+
email = '{{USER_EMAIL}}',
|
|
12
|
+
auth_provider = 'companyhelm',
|
|
13
|
+
updated_at = NOW()
|
|
14
|
+
WHERE id = '{{USER_ID}}'
|
|
15
|
+
OR email = '{{USER_EMAIL}}';
|
|
16
|
+
|
|
8
17
|
INSERT INTO users (id, first_name, last_name, email, auth_provider, created_at, updated_at)
|
|
9
|
-
|
|
18
|
+
SELECT
|
|
10
19
|
'{{USER_ID}}',
|
|
11
20
|
'{{USER_FIRST_NAME}}',
|
|
12
21
|
NULL,
|
|
@@ -14,14 +23,24 @@ VALUES (
|
|
|
14
23
|
'companyhelm',
|
|
15
24
|
NOW(),
|
|
16
25
|
NOW()
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
26
|
+
WHERE NOT EXISTS (
|
|
27
|
+
SELECT 1
|
|
28
|
+
FROM users
|
|
29
|
+
WHERE id = '{{USER_ID}}'
|
|
30
|
+
OR email = '{{USER_EMAIL}}'
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
UPDATE user_auths
|
|
34
|
+
SET user_id = '{{USER_ID}}',
|
|
35
|
+
email = '{{USER_EMAIL}}',
|
|
36
|
+
password_salt = '{{PASSWORD_SALT}}',
|
|
37
|
+
password_hash = '{{PASSWORD_HASH}}',
|
|
38
|
+
updated_at = NOW()
|
|
39
|
+
WHERE user_id = '{{USER_ID}}'
|
|
40
|
+
OR email = '{{USER_EMAIL}}';
|
|
22
41
|
|
|
23
42
|
INSERT INTO user_auths (id, user_id, email, password_salt, password_hash, created_at, updated_at)
|
|
24
|
-
|
|
43
|
+
SELECT
|
|
25
44
|
'{{USER_AUTH_ID}}',
|
|
26
45
|
'{{USER_ID}}',
|
|
27
46
|
'{{USER_EMAIL}}',
|
|
@@ -29,12 +48,12 @@ VALUES (
|
|
|
29
48
|
'{{PASSWORD_HASH}}',
|
|
30
49
|
NOW(),
|
|
31
50
|
NOW()
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
51
|
+
WHERE NOT EXISTS (
|
|
52
|
+
SELECT 1
|
|
53
|
+
FROM user_auths
|
|
54
|
+
WHERE user_id = '{{USER_ID}}'
|
|
55
|
+
OR email = '{{USER_EMAIL}}'
|
|
56
|
+
);
|
|
38
57
|
|
|
39
58
|
INSERT INTO company_members (company_id, user_id)
|
|
40
59
|
VALUES ('{{COMPANY_ID}}', '{{USER_ID}}')
|