alpic 0.0.0-staging.2ab71bc → 0.0.0-staging.2ba052d
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 +40 -0
- package/bin/run.js +5 -0
- package/dist/__tests__/alpic-command.test.d.ts +1 -0
- package/dist/__tests__/alpic-command.test.js +41 -0
- package/dist/__tests__/alpic-command.test.js.map +1 -0
- package/dist/__tests__/audit.e2e.test.d.ts +1 -0
- package/dist/__tests__/audit.e2e.test.js +561 -0
- package/dist/__tests__/audit.e2e.test.js.map +1 -0
- package/dist/__tests__/auth.e2e.test.js +38 -18
- package/dist/__tests__/auth.e2e.test.js.map +1 -1
- package/dist/__tests__/deploy-flags.e2e.test.d.ts +1 -0
- package/dist/__tests__/deploy-flags.e2e.test.js +228 -0
- package/dist/__tests__/deploy-flags.e2e.test.js.map +1 -0
- package/dist/__tests__/deploy.e2e.test.js +33 -66
- package/dist/__tests__/deploy.e2e.test.js.map +1 -1
- package/dist/__tests__/deployment-inspect.e2e.test.d.ts +1 -0
- package/dist/__tests__/deployment-inspect.e2e.test.js +119 -0
- package/dist/__tests__/deployment-inspect.e2e.test.js.map +1 -0
- package/dist/__tests__/deployment-list.e2e.test.d.ts +1 -0
- package/dist/__tests__/deployment-list.e2e.test.js +121 -0
- package/dist/__tests__/deployment-list.e2e.test.js.map +1 -0
- package/dist/__tests__/deployment-logs.e2e.test.d.ts +1 -0
- package/dist/__tests__/deployment-logs.e2e.test.js +262 -0
- package/dist/__tests__/deployment-logs.e2e.test.js.map +1 -0
- package/dist/__tests__/environment-inspect.e2e.test.d.ts +1 -0
- package/dist/__tests__/environment-inspect.e2e.test.js +78 -0
- package/dist/__tests__/environment-inspect.e2e.test.js.map +1 -0
- package/dist/__tests__/environment-list.e2e.test.d.ts +1 -0
- package/dist/__tests__/environment-list.e2e.test.js +63 -0
- package/dist/__tests__/environment-list.e2e.test.js.map +1 -0
- package/dist/__tests__/environment-variable/environment-variable-add.e2e.test.d.ts +1 -0
- package/dist/__tests__/environment-variable/environment-variable-add.e2e.test.js +277 -0
- package/dist/__tests__/environment-variable/environment-variable-add.e2e.test.js.map +1 -0
- package/dist/__tests__/environment-variable/environment-variable-list.e2e.test.d.ts +1 -0
- package/dist/__tests__/environment-variable/environment-variable-list.e2e.test.js +146 -0
- package/dist/__tests__/environment-variable/environment-variable-list.e2e.test.js.map +1 -0
- package/dist/__tests__/environment-variable/environment-variable-remove.e2e.test.d.ts +1 -0
- package/dist/__tests__/environment-variable/environment-variable-remove.e2e.test.js +148 -0
- package/dist/__tests__/environment-variable/environment-variable-remove.e2e.test.js.map +1 -0
- package/dist/__tests__/environment-variable/environment-variable-update.e2e.test.d.ts +1 -0
- package/dist/__tests__/environment-variable/environment-variable-update.e2e.test.js +348 -0
- package/dist/__tests__/environment-variable/environment-variable-update.e2e.test.js.map +1 -0
- package/dist/__tests__/environment-variable/environment-variable-validation.test.d.ts +1 -0
- package/dist/__tests__/environment-variable/environment-variable-validation.test.js +20 -0
- package/dist/__tests__/environment-variable/environment-variable-validation.test.js.map +1 -0
- package/dist/__tests__/fixtures/demo-project/index.js +1 -1
- package/dist/__tests__/fixtures/demo-project/index.js.map +1 -1
- package/dist/__tests__/git-flags.e2e.test.d.ts +1 -0
- package/dist/__tests__/git-flags.e2e.test.js +129 -0
- package/dist/__tests__/git-flags.e2e.test.js.map +1 -0
- package/dist/__tests__/git.e2e.test.js +25 -17
- package/dist/__tests__/git.e2e.test.js.map +1 -1
- package/dist/__tests__/link.e2e.test.d.ts +1 -0
- package/dist/__tests__/link.e2e.test.js +282 -0
- package/dist/__tests__/link.e2e.test.js.map +1 -0
- package/dist/__tests__/logs.e2e.test.d.ts +1 -0
- package/dist/__tests__/logs.e2e.test.js +230 -0
- package/dist/__tests__/logs.e2e.test.js.map +1 -0
- package/dist/__tests__/mock-server.d.ts +25 -0
- package/dist/__tests__/mock-server.js +386 -23
- package/dist/__tests__/mock-server.js.map +1 -1
- package/dist/__tests__/playground/playground-configure.e2e.test.d.ts +1 -0
- package/dist/__tests__/playground/playground-configure.e2e.test.js +135 -0
- package/dist/__tests__/playground/playground-configure.e2e.test.js.map +1 -0
- package/dist/__tests__/playground/playground-enable-disable.e2e.test.d.ts +1 -0
- package/dist/__tests__/playground/playground-enable-disable.e2e.test.js +104 -0
- package/dist/__tests__/playground/playground-enable-disable.e2e.test.js.map +1 -0
- package/dist/__tests__/playground/playground-example-prompt.e2e.test.d.ts +1 -0
- package/dist/__tests__/playground/playground-example-prompt.e2e.test.js +282 -0
- package/dist/__tests__/playground/playground-example-prompt.e2e.test.js.map +1 -0
- package/dist/__tests__/playground/playground-headers.e2e.test.d.ts +1 -0
- package/dist/__tests__/playground/playground-headers.e2e.test.js +324 -0
- package/dist/__tests__/playground/playground-headers.e2e.test.js.map +1 -0
- package/dist/__tests__/playground/playground-status.e2e.test.d.ts +1 -0
- package/dist/__tests__/playground/playground-status.e2e.test.js +88 -0
- package/dist/__tests__/playground/playground-status.e2e.test.js.map +1 -0
- package/dist/__tests__/project-inspect.e2e.test.d.ts +1 -0
- package/dist/__tests__/project-inspect.e2e.test.js +83 -0
- package/dist/__tests__/project-inspect.e2e.test.js.map +1 -0
- package/dist/__tests__/project-list.e2e.test.d.ts +1 -0
- package/dist/__tests__/project-list.e2e.test.js +95 -0
- package/dist/__tests__/project-list.e2e.test.js.map +1 -0
- package/dist/__tests__/publish.e2e.test.d.ts +1 -0
- package/dist/__tests__/publish.e2e.test.js +575 -0
- package/dist/__tests__/publish.e2e.test.js.map +1 -0
- package/dist/__tests__/team-inspect.e2e.test.d.ts +1 -0
- package/dist/__tests__/team-inspect.e2e.test.js +86 -0
- package/dist/__tests__/team-inspect.e2e.test.js.map +1 -0
- package/dist/__tests__/team-list.e2e.test.d.ts +1 -0
- package/dist/__tests__/team-list.e2e.test.js +58 -0
- package/dist/__tests__/team-list.e2e.test.js.map +1 -0
- package/dist/__tests__/tunnel.e2e.test.d.ts +1 -0
- package/dist/__tests__/tunnel.e2e.test.js +66 -0
- package/dist/__tests__/tunnel.e2e.test.js.map +1 -0
- package/dist/__tests__/utils.d.ts +17 -5
- package/dist/__tests__/utils.js +120 -26
- package/dist/__tests__/utils.js.map +1 -1
- package/dist/api.d.ts +1 -1
- package/dist/api.js +10 -3
- package/dist/api.js.map +1 -1
- package/dist/commands/audit.d.ts +13 -0
- package/dist/commands/audit.js +45 -0
- package/dist/commands/audit.js.map +1 -0
- package/dist/commands/deploy.d.ts +7 -2
- package/dist/commands/deploy.js +67 -25
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/deployment/inspect.d.ts +11 -0
- package/dist/commands/deployment/inspect.js +91 -0
- package/dist/commands/deployment/inspect.js.map +1 -0
- package/dist/commands/deployment/list.d.ts +11 -0
- package/dist/commands/deployment/list.js +97 -0
- package/dist/commands/deployment/list.js.map +1 -0
- package/dist/commands/deployment/logs.d.ts +12 -0
- package/dist/commands/deployment/logs.js +50 -0
- package/dist/commands/deployment/logs.js.map +1 -0
- package/dist/commands/environment/inspect.d.ts +10 -0
- package/dist/commands/environment/inspect.js +94 -0
- package/dist/commands/environment/inspect.js.map +1 -0
- package/dist/commands/environment/list.d.ts +10 -0
- package/dist/commands/environment/list.js +79 -0
- package/dist/commands/environment/list.js.map +1 -0
- package/dist/commands/environment-variable/add.d.ts +13 -0
- package/dist/commands/environment-variable/add.js +43 -0
- package/dist/commands/environment-variable/add.js.map +1 -0
- package/dist/commands/environment-variable/list.d.ts +9 -0
- package/dist/commands/environment-variable/list.js +45 -0
- package/dist/commands/environment-variable/list.js.map +1 -0
- package/dist/commands/environment-variable/remove.d.ts +10 -0
- package/dist/commands/environment-variable/remove.js +29 -0
- package/dist/commands/environment-variable/remove.js.map +1 -0
- package/dist/commands/environment-variable/update.d.ts +12 -0
- package/dist/commands/environment-variable/update.js +37 -0
- package/dist/commands/environment-variable/update.js.map +1 -0
- package/dist/commands/git/connect.d.ts +2 -2
- package/dist/commands/git/connect.js +25 -28
- package/dist/commands/git/connect.js.map +1 -1
- package/dist/commands/git/disconnect.d.ts +0 -3
- package/dist/commands/git/disconnect.js +14 -29
- package/dist/commands/git/disconnect.js.map +1 -1
- package/dist/commands/git.js +2 -2
- package/dist/commands/git.js.map +1 -1
- package/dist/commands/link.d.ts +16 -0
- package/dist/commands/link.js +97 -0
- package/dist/commands/link.js.map +1 -0
- package/dist/commands/login.js +6 -24
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/logs.d.ts +16 -0
- package/dist/commands/logs.js +96 -0
- package/dist/commands/logs.js.map +1 -0
- package/dist/commands/playground/configure.d.ts +12 -0
- package/dist/commands/playground/configure.js +39 -0
- package/dist/commands/playground/configure.js.map +1 -0
- package/dist/commands/playground/disable.d.ts +9 -0
- package/dist/commands/playground/disable.js +24 -0
- package/dist/commands/playground/disable.js.map +1 -0
- package/dist/commands/playground/enable.d.ts +9 -0
- package/dist/commands/playground/enable.js +24 -0
- package/dist/commands/playground/enable.js.map +1 -0
- package/dist/commands/playground/example-prompt/add.d.ts +12 -0
- package/dist/commands/playground/example-prompt/add.js +39 -0
- package/dist/commands/playground/example-prompt/add.js.map +1 -0
- package/dist/commands/playground/example-prompt/list.d.ts +9 -0
- package/dist/commands/playground/example-prompt/list.js +24 -0
- package/dist/commands/playground/example-prompt/list.js.map +1 -0
- package/dist/commands/playground/example-prompt/remove.d.ts +11 -0
- package/dist/commands/playground/example-prompt/remove.js +34 -0
- package/dist/commands/playground/example-prompt/remove.js.map +1 -0
- package/dist/commands/playground/headers/add.d.ts +14 -0
- package/dist/commands/playground/headers/add.js +49 -0
- package/dist/commands/playground/headers/add.js.map +1 -0
- package/dist/commands/playground/headers/list.d.ts +9 -0
- package/dist/commands/playground/headers/list.js +24 -0
- package/dist/commands/playground/headers/list.js.map +1 -0
- package/dist/commands/playground/headers/remove.d.ts +11 -0
- package/dist/commands/playground/headers/remove.js +34 -0
- package/dist/commands/playground/headers/remove.js.map +1 -0
- package/dist/commands/playground/status.d.ts +9 -0
- package/dist/commands/playground/status.js +24 -0
- package/dist/commands/playground/status.js.map +1 -0
- package/dist/commands/project/inspect.d.ts +10 -0
- package/dist/commands/project/inspect.js +97 -0
- package/dist/commands/project/inspect.js.map +1 -0
- package/dist/commands/project/list.d.ts +10 -0
- package/dist/commands/project/list.js +50 -0
- package/dist/commands/project/list.js.map +1 -0
- package/dist/commands/publish.d.ts +14 -0
- package/dist/commands/publish.js +47 -0
- package/dist/commands/publish.js.map +1 -0
- package/dist/commands/team/inspect.d.ts +10 -0
- package/dist/commands/team/inspect.js +97 -0
- package/dist/commands/team/inspect.js.map +1 -0
- package/dist/commands/team/list.d.ts +9 -0
- package/dist/commands/team/list.js +40 -0
- package/dist/commands/team/list.js.map +1 -0
- package/dist/commands/tunnel.d.ts +10 -0
- package/dist/commands/tunnel.js +132 -0
- package/dist/commands/tunnel.js.map +1 -0
- package/dist/commands/whoami.js +2 -14
- package/dist/commands/whoami.js.map +1 -1
- package/dist/env.js +1 -1
- package/dist/env.js.map +1 -1
- package/dist/lib/alpic-command.d.ts +7 -0
- package/dist/lib/alpic-command.js +24 -6
- package/dist/lib/alpic-command.js.map +1 -1
- package/dist/lib/archive.d.ts +3 -3
- package/dist/lib/archive.js +21 -19
- package/dist/lib/archive.js.map +1 -1
- package/dist/lib/audit.d.ts +16 -0
- package/dist/lib/audit.js +258 -0
- package/dist/lib/audit.js.map +1 -0
- package/dist/lib/auth/auth.d.ts +3 -0
- package/dist/lib/auth/auth.js +26 -3
- package/dist/lib/auth/auth.js.map +1 -1
- package/dist/lib/auth/oauth/client.d.ts +1 -1
- package/dist/lib/auth/oauth/client.js +7 -1
- package/dist/lib/auth/oauth/client.js.map +1 -1
- package/dist/lib/auth/oauth/server/index.d.ts +2 -1
- package/dist/lib/auth/oauth/server/index.js +36 -10
- package/dist/lib/auth/oauth/server/index.js.map +1 -1
- package/dist/lib/auth/whoami.d.ts +1 -28
- package/dist/lib/auth/whoami.js +29 -19
- package/dist/lib/auth/whoami.js.map +1 -1
- package/dist/lib/base-workflow.d.ts +10 -0
- package/dist/lib/base-workflow.js +22 -0
- package/dist/lib/base-workflow.js.map +1 -0
- package/dist/lib/config.d.ts +3 -2
- package/dist/lib/config.js +8 -7
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/deployment.d.ts +69 -1
- package/dist/lib/deployment.js +113 -5
- package/dist/lib/deployment.js.map +1 -1
- package/dist/lib/environment-variable.d.ts +37 -0
- package/dist/lib/environment-variable.js +305 -0
- package/dist/lib/environment-variable.js.map +1 -0
- package/dist/lib/git.d.ts +12 -4
- package/dist/lib/git.js +52 -26
- package/dist/lib/git.js.map +1 -1
- package/dist/lib/global-store.d.ts +1 -1
- package/dist/lib/global-store.js +4 -3
- package/dist/lib/global-store.js.map +1 -1
- package/dist/lib/link.d.ts +83 -0
- package/dist/lib/link.js +387 -0
- package/dist/lib/link.js.map +1 -0
- package/dist/lib/logs.d.ts +20 -0
- package/dist/lib/logs.js +87 -0
- package/dist/lib/logs.js.map +1 -0
- package/dist/lib/playground.d.ts +53 -0
- package/dist/lib/playground.js +288 -0
- package/dist/lib/playground.js.map +1 -0
- package/dist/lib/publish.d.ts +22 -0
- package/dist/lib/publish.js +201 -0
- package/dist/lib/publish.js.map +1 -0
- package/dist/lib/resolve.d.ts +6 -0
- package/dist/lib/resolve.js +26 -0
- package/dist/lib/resolve.js.map +1 -0
- package/dist/lib/table.d.ts +8 -0
- package/dist/lib/table.js +27 -0
- package/dist/lib/table.js.map +1 -0
- package/dist/lib/telemetry.js +1 -1
- package/dist/lib/telemetry.js.map +1 -1
- package/dist/lib/utils.d.ts +6 -0
- package/dist/lib/utils.js +54 -0
- package/dist/lib/utils.js.map +1 -0
- package/dist/lib/utils.test.d.ts +1 -0
- package/dist/lib/utils.test.js +27 -0
- package/dist/lib/utils.test.js.map +1 -0
- package/dist/types.d.ts +1 -0
- package/package.json +28 -21
- package/dist/lib/project.d.ts +0 -67
- package/dist/lib/project.js +0 -285
- package/dist/lib/project.js.map +0 -1
package/dist/lib/git.js
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
|
+
import { execFileSync } from "node:child_process";
|
|
1
2
|
import * as p from "@clack/prompts";
|
|
2
3
|
import chalk from "chalk";
|
|
3
|
-
import {
|
|
4
|
-
function runGit(args
|
|
4
|
+
import { BaseWorkflow } from "./base-workflow.js";
|
|
5
|
+
function runGit(args) {
|
|
5
6
|
return execFileSync("git", args, {
|
|
6
|
-
cwd,
|
|
7
7
|
encoding: "utf8",
|
|
8
8
|
stdio: ["ignore", "pipe", "pipe"],
|
|
9
9
|
}).trim();
|
|
10
10
|
}
|
|
11
|
-
export function isGitRepository(
|
|
11
|
+
export function isGitRepository() {
|
|
12
12
|
try {
|
|
13
|
-
return runGit(["rev-parse", "--is-inside-work-tree"]
|
|
13
|
+
return runGit(["rev-parse", "--is-inside-work-tree"]) === "true";
|
|
14
14
|
}
|
|
15
15
|
catch {
|
|
16
16
|
return false;
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
|
-
export function listGithubRemotes(
|
|
19
|
+
export function listGithubRemotes() {
|
|
20
20
|
let output;
|
|
21
21
|
try {
|
|
22
|
-
output = runGit(["remote", "-v"]
|
|
22
|
+
output = runGit(["remote", "-v"]);
|
|
23
23
|
}
|
|
24
24
|
catch {
|
|
25
25
|
return [];
|
|
@@ -50,7 +50,7 @@ export function listGithubRemotes(cwd) {
|
|
|
50
50
|
}
|
|
51
51
|
export async function confirmLinkAnotherIfAlreadyConnected(project) {
|
|
52
52
|
if (!project.sourceRepository) {
|
|
53
|
-
return
|
|
53
|
+
return;
|
|
54
54
|
}
|
|
55
55
|
p.log.info(`Project "${project.name}" is already connected to "${project.sourceRepository}".`);
|
|
56
56
|
const confirm = await p.confirm({
|
|
@@ -58,28 +58,54 @@ export async function confirmLinkAnotherIfAlreadyConnected(project) {
|
|
|
58
58
|
initialValue: false,
|
|
59
59
|
});
|
|
60
60
|
if (p.isCancel(confirm) || !confirm) {
|
|
61
|
-
|
|
62
|
-
return false;
|
|
61
|
+
throw new Error("Git connect cancelled");
|
|
63
62
|
}
|
|
64
|
-
return true;
|
|
65
63
|
}
|
|
66
|
-
export
|
|
67
|
-
|
|
68
|
-
|
|
64
|
+
export class GitWorkflow extends BaseWorkflow {
|
|
65
|
+
async confirmDisconnect(sourceRepository, projectName) {
|
|
66
|
+
const confirmed = await this.confirm({
|
|
67
|
+
message: `Are you sure you want to disconnect ${chalk.bold(sourceRepository)} from project ${chalk.bold(projectName)}?`,
|
|
68
|
+
initialValue: false,
|
|
69
|
+
});
|
|
70
|
+
if (p.isCancel(confirmed))
|
|
71
|
+
return false;
|
|
72
|
+
return confirmed === true;
|
|
69
73
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
74
|
+
async selectRemoteSourceRepository(remotes) {
|
|
75
|
+
if (remotes.length === 0) {
|
|
76
|
+
throw new Error("No remotes found. Add a remote first.");
|
|
77
|
+
}
|
|
78
|
+
if (this.flags.remoteName) {
|
|
79
|
+
const remote = remotes.find((remote) => remote.name === this.flags.remoteName);
|
|
80
|
+
if (!remote) {
|
|
81
|
+
const available = remotes.map((remote) => remote.name).join(", ");
|
|
82
|
+
throw new Error(`Remote "${this.flags.remoteName}" not found. Available remotes: ${available}`);
|
|
83
|
+
}
|
|
84
|
+
return remote.sourceRepository;
|
|
85
|
+
}
|
|
86
|
+
if (this.isNonInteractive()) {
|
|
87
|
+
if (remotes.length !== 1) {
|
|
88
|
+
throw new Error("Multiple remotes found. Use --remote-name to select a specific remote.");
|
|
89
|
+
}
|
|
90
|
+
const singleRemote = remotes.at(0);
|
|
91
|
+
if (!singleRemote) {
|
|
92
|
+
throw new Error("No remote found.");
|
|
93
|
+
}
|
|
94
|
+
return singleRemote.sourceRepository;
|
|
95
|
+
}
|
|
96
|
+
const selected = await p.select({
|
|
97
|
+
message: chalk.bold("Choose the remote source to connect"),
|
|
98
|
+
options: remotes.map((remote) => ({
|
|
99
|
+
value: remote.sourceRepository,
|
|
100
|
+
label: `${remote.sourceRepository} (${remote.name})`,
|
|
101
|
+
hint: remote.url,
|
|
102
|
+
})),
|
|
103
|
+
});
|
|
104
|
+
if (p.isCancel(selected)) {
|
|
105
|
+
throw new Error("No remote source repository selected.");
|
|
106
|
+
}
|
|
107
|
+
return selected;
|
|
81
108
|
}
|
|
82
|
-
return selected;
|
|
83
109
|
}
|
|
84
110
|
export function showGitSetupInstructions() {
|
|
85
111
|
p.note([
|
package/dist/lib/git.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/lib/git.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/lib/git.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,7 +12,7 @@ export interface Config {
|
|
|
12
12
|
}
|
|
13
13
|
export declare class GlobalStore {
|
|
14
14
|
private readonly configDir;
|
|
15
|
-
constructor(
|
|
15
|
+
constructor();
|
|
16
16
|
getCredentials(): Credentials | null;
|
|
17
17
|
saveCredentials(credentials: Credentials): void;
|
|
18
18
|
clearCredentials(): void;
|
package/dist/lib/global-store.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import crypto from "node:crypto";
|
|
2
2
|
import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
|
|
3
3
|
import { join } from "node:path";
|
|
4
|
-
import
|
|
4
|
+
import envPaths from "env-paths";
|
|
5
5
|
export class GlobalStore {
|
|
6
6
|
configDir;
|
|
7
|
-
constructor(
|
|
8
|
-
|
|
7
|
+
constructor() {
|
|
8
|
+
const configDirOverride = process.env.ALPIC_GLOBAL_CONFIG_DIR;
|
|
9
|
+
this.configDir = configDirOverride ?? envPaths("alpic", { suffix: "" }).config;
|
|
9
10
|
}
|
|
10
11
|
getCredentials() {
|
|
11
12
|
const token = this.parseJsonFile(this.getCredentialsFilePath());
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"global-store.js","sourceRoot":"","sources":["../../src/lib/global-store.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACzF,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,
|
|
1
|
+
{"version":3,"file":"global-store.js","sourceRoot":"","sources":["../../src/lib/global-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { RouterOutput, Runtime } from "@alpic-ai/api";
|
|
2
|
+
import type { ProjectConfig } from "../types.js";
|
|
3
|
+
import { BaseWorkflow } from "./base-workflow.js";
|
|
4
|
+
export declare const RUNTIMES: ("python3.13" | "python3.14" | "node22" | "node24")[];
|
|
5
|
+
export type LinkFlags = {
|
|
6
|
+
"non-interactive"?: boolean;
|
|
7
|
+
teamId?: string;
|
|
8
|
+
projectId?: string;
|
|
9
|
+
environmentId?: string;
|
|
10
|
+
projectName?: string;
|
|
11
|
+
runtime?: Runtime;
|
|
12
|
+
rootDir?: string;
|
|
13
|
+
};
|
|
14
|
+
export declare class LinkWorkflow extends BaseWorkflow<LinkFlags> {
|
|
15
|
+
confirmWorkingDirectory(): Promise<boolean | null>;
|
|
16
|
+
confirmLinkExisting(): Promise<boolean | null>;
|
|
17
|
+
confirmLinkToAnotherProject(): Promise<boolean | null>;
|
|
18
|
+
selectProjectFromList(projects: RouterOutput["projects"]["list"]["v1"]): Promise<{
|
|
19
|
+
id: string;
|
|
20
|
+
name: string;
|
|
21
|
+
teamId: string;
|
|
22
|
+
sourceRepository: string | null;
|
|
23
|
+
runtime: "python3.13" | "python3.14" | "node22" | "node24";
|
|
24
|
+
transport: "stdio" | "sse" | "streamablehttp" | null;
|
|
25
|
+
rootDirectory: string | null;
|
|
26
|
+
buildCommand: string | null;
|
|
27
|
+
buildOutputDir: string | null;
|
|
28
|
+
installCommand: string | null;
|
|
29
|
+
startCommand: string | null;
|
|
30
|
+
createdAt: Date;
|
|
31
|
+
productionEnvironment: {
|
|
32
|
+
id: string;
|
|
33
|
+
name: string;
|
|
34
|
+
mcpServerUrl: string;
|
|
35
|
+
domains: {
|
|
36
|
+
domain: string;
|
|
37
|
+
status: "failed" | "ongoing" | "deployed";
|
|
38
|
+
createdAt: Date;
|
|
39
|
+
}[];
|
|
40
|
+
latestDeployment: {
|
|
41
|
+
id: string;
|
|
42
|
+
status: "failed" | "ongoing" | "deployed" | "canceled";
|
|
43
|
+
sourceCommitId: string | null;
|
|
44
|
+
sourceCommitMessage: string | null;
|
|
45
|
+
completedAt: Date | null;
|
|
46
|
+
} | null;
|
|
47
|
+
} | null;
|
|
48
|
+
environments: {
|
|
49
|
+
id: string;
|
|
50
|
+
name: string;
|
|
51
|
+
sourceBranch: string | null;
|
|
52
|
+
mcpServerUrl: string;
|
|
53
|
+
createdAt: Date;
|
|
54
|
+
projectId: string;
|
|
55
|
+
latestDeployment: {
|
|
56
|
+
id: string;
|
|
57
|
+
status: "failed" | "ongoing" | "deployed" | "canceled";
|
|
58
|
+
sourceCommitId: string | null;
|
|
59
|
+
sourceCommitMessage: string | null;
|
|
60
|
+
completedAt: Date | null;
|
|
61
|
+
} | null;
|
|
62
|
+
}[];
|
|
63
|
+
} | null>;
|
|
64
|
+
selectEnvironmentFromList(environments: RouterOutput["projects"]["get"]["v1"]["environments"]): Promise<(typeof environments)[number] | null>;
|
|
65
|
+
resolveTeam(): Promise<{
|
|
66
|
+
id: string;
|
|
67
|
+
name: string;
|
|
68
|
+
} | null>;
|
|
69
|
+
promptRootDirectory(): Promise<string | null>;
|
|
70
|
+
confirmDeployWithExistingConfig(existingConfig: ProjectConfig): Promise<boolean | null>;
|
|
71
|
+
runLinkFlow(): Promise<(ProjectConfig & {
|
|
72
|
+
environmentId: string;
|
|
73
|
+
}) | null>;
|
|
74
|
+
resolveEnvironmentForProject(projectId: string): Promise<{
|
|
75
|
+
environmentId: string;
|
|
76
|
+
environmentName: string;
|
|
77
|
+
} | null>;
|
|
78
|
+
private getConfigFromFlags;
|
|
79
|
+
private directoryExists;
|
|
80
|
+
private detectRuntime;
|
|
81
|
+
private runCreateProjectFlow;
|
|
82
|
+
private runLinkingFlow;
|
|
83
|
+
}
|
package/dist/lib/link.js
ADDED
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { runtimeSchema } from "@alpic-ai/api";
|
|
4
|
+
import * as p from "@clack/prompts";
|
|
5
|
+
import chalk from "chalk";
|
|
6
|
+
import { api } from "../api.js";
|
|
7
|
+
import { BaseWorkflow } from "./base-workflow.js";
|
|
8
|
+
import { config } from "./config.js";
|
|
9
|
+
export const RUNTIMES = runtimeSchema.options;
|
|
10
|
+
const RUNTIME_LABELS = {
|
|
11
|
+
node24: "Node.js 24",
|
|
12
|
+
node22: "Node.js 22",
|
|
13
|
+
"python3.14": "Python 3.14",
|
|
14
|
+
"python3.13": "Python 3.13",
|
|
15
|
+
};
|
|
16
|
+
export class LinkWorkflow extends BaseWorkflow {
|
|
17
|
+
async confirmWorkingDirectory() {
|
|
18
|
+
const confirmed = await this.confirm({
|
|
19
|
+
message: chalk.bold(`Use the current directory? `) + chalk.cyan(process.cwd()),
|
|
20
|
+
initialValue: true,
|
|
21
|
+
});
|
|
22
|
+
if (p.isCancel(confirmed))
|
|
23
|
+
return null;
|
|
24
|
+
return confirmed === true;
|
|
25
|
+
}
|
|
26
|
+
async confirmLinkExisting() {
|
|
27
|
+
const link = await this.confirm({
|
|
28
|
+
message: chalk.bold("Link to existing project?"),
|
|
29
|
+
initialValue: true,
|
|
30
|
+
}, false);
|
|
31
|
+
if (p.isCancel(link))
|
|
32
|
+
return null;
|
|
33
|
+
return link === true;
|
|
34
|
+
}
|
|
35
|
+
async confirmLinkToAnotherProject() {
|
|
36
|
+
const link = await this.confirm({
|
|
37
|
+
message: chalk.bold("Link to another project?"),
|
|
38
|
+
initialValue: true,
|
|
39
|
+
}, false);
|
|
40
|
+
if (p.isCancel(link))
|
|
41
|
+
return null;
|
|
42
|
+
return link === true;
|
|
43
|
+
}
|
|
44
|
+
async selectProjectFromList(projects) {
|
|
45
|
+
if (projects.length === 0) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
const choice = await p.select({
|
|
49
|
+
message: chalk.bold("Choose a project"),
|
|
50
|
+
options: projects.map((proj) => ({ value: proj.id, label: proj.name })),
|
|
51
|
+
});
|
|
52
|
+
if (p.isCancel(choice))
|
|
53
|
+
return null;
|
|
54
|
+
const project = projects.find((proj) => proj.id === choice);
|
|
55
|
+
return project ?? null;
|
|
56
|
+
}
|
|
57
|
+
async selectEnvironmentFromList(environments) {
|
|
58
|
+
if (environments.length === 0) {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
const choice = await p.select({
|
|
62
|
+
message: chalk.bold("Choose an environment to deploy to"),
|
|
63
|
+
options: environments.map((env) => ({
|
|
64
|
+
value: env.id,
|
|
65
|
+
label: env.sourceBranch ? `${env.name} (${env.sourceBranch})` : env.name,
|
|
66
|
+
})),
|
|
67
|
+
});
|
|
68
|
+
if (p.isCancel(choice))
|
|
69
|
+
return null;
|
|
70
|
+
const environment = environments.find((e) => e.id === choice);
|
|
71
|
+
return environment ?? null;
|
|
72
|
+
}
|
|
73
|
+
async resolveTeam() {
|
|
74
|
+
const teams = await api.teams.list.v1();
|
|
75
|
+
if (teams.length === 0) {
|
|
76
|
+
throw new Error("No teams found. Create a team in the Alpic dashboard first.");
|
|
77
|
+
}
|
|
78
|
+
if (this.flags.teamId) {
|
|
79
|
+
const match = teams.find((t) => t.id === this.flags.teamId);
|
|
80
|
+
if (!match) {
|
|
81
|
+
throw new Error(`Team "${this.flags.teamId}" not found.`);
|
|
82
|
+
}
|
|
83
|
+
return match;
|
|
84
|
+
}
|
|
85
|
+
if (teams.length === 1) {
|
|
86
|
+
const singleTeam = teams[0];
|
|
87
|
+
if (!singleTeam) {
|
|
88
|
+
throw new Error("No teams found.");
|
|
89
|
+
}
|
|
90
|
+
p.log.info(`Using team ${chalk.bold(singleTeam.name)}`);
|
|
91
|
+
return singleTeam;
|
|
92
|
+
}
|
|
93
|
+
if (this.isNonInteractive()) {
|
|
94
|
+
throw new Error("Multiple teams found. Use --team-id to select one.");
|
|
95
|
+
}
|
|
96
|
+
const choice = await p.select({
|
|
97
|
+
message: chalk.bold("Choose a team"),
|
|
98
|
+
options: teams.map((t) => ({ value: t.id, label: t.name })),
|
|
99
|
+
});
|
|
100
|
+
if (p.isCancel(choice))
|
|
101
|
+
return null;
|
|
102
|
+
const selected = teams.find((t) => t.id === choice);
|
|
103
|
+
return selected ?? null;
|
|
104
|
+
}
|
|
105
|
+
async promptRootDirectory() {
|
|
106
|
+
if (this.isNonInteractive()) {
|
|
107
|
+
if (this.flags.rootDir) {
|
|
108
|
+
const trimmed = this.flags.rootDir.trim();
|
|
109
|
+
if (trimmed === "" || trimmed === ".")
|
|
110
|
+
return null;
|
|
111
|
+
if (!this.directoryExists(trimmed)) {
|
|
112
|
+
throw new Error(`Directory does not exist: ${resolve(trimmed)}`);
|
|
113
|
+
}
|
|
114
|
+
return trimmed;
|
|
115
|
+
}
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
while (true) {
|
|
119
|
+
const rootDir = await p.text({
|
|
120
|
+
message: chalk.bold("Root directory"),
|
|
121
|
+
placeholder: ".",
|
|
122
|
+
initialValue: ".",
|
|
123
|
+
validate: (value) => {
|
|
124
|
+
if (value != null && value.length > 512)
|
|
125
|
+
return "Path must be at most 512 characters.";
|
|
126
|
+
return undefined;
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
if (p.isCancel(rootDir))
|
|
130
|
+
return null;
|
|
131
|
+
const trimmed = rootDir.trim();
|
|
132
|
+
if (trimmed === "" || trimmed === ".")
|
|
133
|
+
return null;
|
|
134
|
+
if (!this.directoryExists(trimmed)) {
|
|
135
|
+
p.log.error(`Directory does not exist: ${trimmed}`);
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
return trimmed;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
async confirmDeployWithExistingConfig(existingConfig) {
|
|
142
|
+
const envLabel = existingConfig.environmentName ? ` to environment "${existingConfig.environmentName}"` : "";
|
|
143
|
+
const teamLabel = existingConfig.teamName ? chalk.dim(` [team: ${existingConfig.teamName}]`) : "";
|
|
144
|
+
const confirmed = await this.confirm({
|
|
145
|
+
message: chalk.bold(`Use project "${existingConfig.projectName}"${envLabel}?`) + teamLabel,
|
|
146
|
+
initialValue: true,
|
|
147
|
+
});
|
|
148
|
+
if (p.isCancel(confirmed))
|
|
149
|
+
return null;
|
|
150
|
+
return confirmed === true;
|
|
151
|
+
}
|
|
152
|
+
async runLinkFlow() {
|
|
153
|
+
const fromFlags = await this.getConfigFromFlags();
|
|
154
|
+
if (fromFlags)
|
|
155
|
+
return fromFlags;
|
|
156
|
+
const ok = await this.confirmWorkingDirectory();
|
|
157
|
+
if (ok === null || ok === false)
|
|
158
|
+
return null;
|
|
159
|
+
const existingConfig = config.load();
|
|
160
|
+
if (existingConfig) {
|
|
161
|
+
let confirmed;
|
|
162
|
+
while (true) {
|
|
163
|
+
confirmed = await this.confirmDeployWithExistingConfig(existingConfig);
|
|
164
|
+
if (confirmed === null)
|
|
165
|
+
return null;
|
|
166
|
+
if (confirmed)
|
|
167
|
+
break;
|
|
168
|
+
const linkAnother = await this.confirmLinkToAnotherProject();
|
|
169
|
+
if (linkAnother === null)
|
|
170
|
+
return null;
|
|
171
|
+
if (linkAnother) {
|
|
172
|
+
const linkExisting = await this.confirmLinkExisting();
|
|
173
|
+
if (linkExisting === null)
|
|
174
|
+
return null;
|
|
175
|
+
if (!linkExisting) {
|
|
176
|
+
return this.runCreateProjectFlow();
|
|
177
|
+
}
|
|
178
|
+
return this.runLinkingFlow();
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
if (existingConfig.environmentId) {
|
|
182
|
+
return {
|
|
183
|
+
projectId: existingConfig.projectId,
|
|
184
|
+
teamId: existingConfig.teamId,
|
|
185
|
+
teamName: existingConfig.teamName,
|
|
186
|
+
projectName: existingConfig.projectName,
|
|
187
|
+
environmentId: existingConfig.environmentId,
|
|
188
|
+
environmentName: existingConfig.environmentName,
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
const env = await this.resolveEnvironmentForProject(existingConfig.projectId);
|
|
192
|
+
if (!env)
|
|
193
|
+
return null;
|
|
194
|
+
const updatedConfig = {
|
|
195
|
+
...existingConfig,
|
|
196
|
+
environmentId: env.environmentId,
|
|
197
|
+
environmentName: env.environmentName,
|
|
198
|
+
};
|
|
199
|
+
config.save(updatedConfig);
|
|
200
|
+
p.note(`Environment "${env.environmentName}" will be used for future deploys.`, undefined, {
|
|
201
|
+
format: (line) => line,
|
|
202
|
+
});
|
|
203
|
+
return updatedConfig;
|
|
204
|
+
}
|
|
205
|
+
const team = await this.resolveTeam();
|
|
206
|
+
if (!team)
|
|
207
|
+
return null;
|
|
208
|
+
const linkExisting = await this.confirmLinkExisting();
|
|
209
|
+
if (linkExisting === null)
|
|
210
|
+
return null;
|
|
211
|
+
if (linkExisting) {
|
|
212
|
+
return this.runLinkingFlow(team);
|
|
213
|
+
}
|
|
214
|
+
return this.runCreateProjectFlow(team);
|
|
215
|
+
}
|
|
216
|
+
async resolveEnvironmentForProject(projectId) {
|
|
217
|
+
const project = await api.projects.get.v1({ projectId });
|
|
218
|
+
const environments = project.environments ?? [];
|
|
219
|
+
if (environments.length === 0) {
|
|
220
|
+
throw new Error("No environments found for this project.");
|
|
221
|
+
}
|
|
222
|
+
const environment = await this.selectEnvironmentFromList(environments);
|
|
223
|
+
if (!environment)
|
|
224
|
+
return null;
|
|
225
|
+
return { environmentId: environment.id, environmentName: environment.name };
|
|
226
|
+
}
|
|
227
|
+
async getConfigFromFlags() {
|
|
228
|
+
const { projectId, environmentId } = this.flags;
|
|
229
|
+
if (projectId && !environmentId) {
|
|
230
|
+
throw new Error("--environment-id is required when using --project-id.");
|
|
231
|
+
}
|
|
232
|
+
if (!projectId && environmentId) {
|
|
233
|
+
throw new Error("--project-id is required when using --environment-id.");
|
|
234
|
+
}
|
|
235
|
+
if (projectId && environmentId) {
|
|
236
|
+
const project = await api.projects.get.v1({ projectId });
|
|
237
|
+
const environment = project.environments?.find((env) => env.id === environmentId);
|
|
238
|
+
if (!environment) {
|
|
239
|
+
throw new Error(`Environment "${environmentId}" not found in project "${project.name}".`);
|
|
240
|
+
}
|
|
241
|
+
const teams = await api.teams.list.v1();
|
|
242
|
+
const team = teams.find((t) => t.id === project.teamId);
|
|
243
|
+
const resolvedConfig = {
|
|
244
|
+
projectId,
|
|
245
|
+
teamId: project.teamId,
|
|
246
|
+
teamName: team?.name,
|
|
247
|
+
projectName: project.name,
|
|
248
|
+
environmentId,
|
|
249
|
+
environmentName: environment.name,
|
|
250
|
+
};
|
|
251
|
+
config.save(resolvedConfig);
|
|
252
|
+
return resolvedConfig;
|
|
253
|
+
}
|
|
254
|
+
return null;
|
|
255
|
+
}
|
|
256
|
+
directoryExists(dir) {
|
|
257
|
+
return existsSync(dir) && statSync(dir).isDirectory();
|
|
258
|
+
}
|
|
259
|
+
detectRuntime() {
|
|
260
|
+
const has = (file) => existsSync(file);
|
|
261
|
+
const read = (file) => {
|
|
262
|
+
try {
|
|
263
|
+
return readFileSync(file, "utf8");
|
|
264
|
+
}
|
|
265
|
+
catch {
|
|
266
|
+
return "";
|
|
267
|
+
}
|
|
268
|
+
};
|
|
269
|
+
if (has("pyproject.toml") || has("requirements.txt") || has("setup.py") || has(".python-version")) {
|
|
270
|
+
return "python3.13";
|
|
271
|
+
}
|
|
272
|
+
if (has("package.json")) {
|
|
273
|
+
const nvmrc = has(".nvmrc") ? (read(".nvmrc").trim().split(/\s/)[0] ?? "") : "";
|
|
274
|
+
const major = nvmrc.replace(/^v/i, "").match(/^(\d+)/)?.[1];
|
|
275
|
+
if (major === "22")
|
|
276
|
+
return "node22";
|
|
277
|
+
return "node24";
|
|
278
|
+
}
|
|
279
|
+
return null;
|
|
280
|
+
}
|
|
281
|
+
async runCreateProjectFlow(team) {
|
|
282
|
+
if (!team) {
|
|
283
|
+
team = (await this.resolveTeam()) ?? undefined;
|
|
284
|
+
if (!team)
|
|
285
|
+
return null;
|
|
286
|
+
}
|
|
287
|
+
if (this.isNonInteractive() && !this.flags.projectName) {
|
|
288
|
+
throw new Error("--project-name is required when using --non-interactive");
|
|
289
|
+
}
|
|
290
|
+
const name = this.flags.projectName ??
|
|
291
|
+
(await p.text({
|
|
292
|
+
message: chalk.bold("Project name"),
|
|
293
|
+
placeholder: "my-app",
|
|
294
|
+
validate: (value) => {
|
|
295
|
+
if (!value?.trim())
|
|
296
|
+
return "Project name is required.";
|
|
297
|
+
if (value.length > 100)
|
|
298
|
+
return "Project name must be at most 100 characters.";
|
|
299
|
+
return undefined;
|
|
300
|
+
},
|
|
301
|
+
}));
|
|
302
|
+
if (p.isCancel(name)) {
|
|
303
|
+
return null;
|
|
304
|
+
}
|
|
305
|
+
const detectedRuntime = this.detectRuntime();
|
|
306
|
+
const defaultRuntime = detectedRuntime ?? "node24";
|
|
307
|
+
const runtime = this.isNonInteractive()
|
|
308
|
+
? (this.flags.runtime ?? defaultRuntime)
|
|
309
|
+
: await p.select({
|
|
310
|
+
message: chalk.bold("Runtime"),
|
|
311
|
+
options: RUNTIMES.map((value) => ({
|
|
312
|
+
value,
|
|
313
|
+
label: value === detectedRuntime ? `${RUNTIME_LABELS[value]} (detected)` : RUNTIME_LABELS[value],
|
|
314
|
+
})),
|
|
315
|
+
initialValue: defaultRuntime,
|
|
316
|
+
});
|
|
317
|
+
if (p.isCancel(runtime)) {
|
|
318
|
+
return null;
|
|
319
|
+
}
|
|
320
|
+
const rootDirectory = await this.promptRootDirectory();
|
|
321
|
+
const spin = p.spinner();
|
|
322
|
+
spin.start("Creating project...");
|
|
323
|
+
try {
|
|
324
|
+
const projectInput = {
|
|
325
|
+
name,
|
|
326
|
+
runtime,
|
|
327
|
+
teamId: team.id,
|
|
328
|
+
};
|
|
329
|
+
projectInput.rootDirectory = rootDirectory ?? undefined;
|
|
330
|
+
const created = await api.projects.create.v1(projectInput);
|
|
331
|
+
spin.stop("Project created.");
|
|
332
|
+
const productionEnv = created.productionEnvironment;
|
|
333
|
+
if (!productionEnv) {
|
|
334
|
+
throw new Error("Project was created but has no Production environment.");
|
|
335
|
+
}
|
|
336
|
+
const newConfig = {
|
|
337
|
+
projectId: created.id,
|
|
338
|
+
teamId: created.teamId,
|
|
339
|
+
teamName: team.name,
|
|
340
|
+
projectName: created.name,
|
|
341
|
+
environmentId: productionEnv.id,
|
|
342
|
+
environmentName: productionEnv.name,
|
|
343
|
+
};
|
|
344
|
+
config.save(newConfig);
|
|
345
|
+
return newConfig;
|
|
346
|
+
}
|
|
347
|
+
catch (error) {
|
|
348
|
+
spin.stop();
|
|
349
|
+
throw error;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
async runLinkingFlow(team) {
|
|
353
|
+
if (!team) {
|
|
354
|
+
team = (await this.resolveTeam()) ?? undefined;
|
|
355
|
+
if (!team)
|
|
356
|
+
return null;
|
|
357
|
+
}
|
|
358
|
+
const projects = await api.projects.list.v1({ teamId: team.id });
|
|
359
|
+
if (projects.length === 0) {
|
|
360
|
+
throw new Error("No projects found. Create a project in the Alpic dashboard first.");
|
|
361
|
+
}
|
|
362
|
+
const project = await this.selectProjectFromList(projects);
|
|
363
|
+
if (!project)
|
|
364
|
+
return null;
|
|
365
|
+
const environments = project.environments ?? [];
|
|
366
|
+
if (environments.length === 0) {
|
|
367
|
+
throw new Error("No environments found for this project.");
|
|
368
|
+
}
|
|
369
|
+
const environment = await this.selectEnvironmentFromList(environments);
|
|
370
|
+
if (!environment)
|
|
371
|
+
return null;
|
|
372
|
+
const newConfig = {
|
|
373
|
+
projectId: project.id,
|
|
374
|
+
teamId: project.teamId,
|
|
375
|
+
teamName: team.name,
|
|
376
|
+
projectName: project.name,
|
|
377
|
+
environmentId: environment.id,
|
|
378
|
+
environmentName: environment.name,
|
|
379
|
+
};
|
|
380
|
+
config.save(newConfig);
|
|
381
|
+
p.note(`Linked to project "${project.name}", environment "${environment.name}".`, undefined, {
|
|
382
|
+
format: (line) => line,
|
|
383
|
+
});
|
|
384
|
+
return newConfig;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
//# sourceMappingURL=link.js.map
|