@getpaseo/cli 0.3.0 → 0.4.0-beta.1
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/cli.js +0 -5
- package/dist/commands/hub/authority.d.ts +17 -0
- package/dist/commands/hub/authority.js +18 -0
- package/dist/commands/hub/connect.d.ts +21 -0
- package/dist/commands/hub/connect.js +34 -0
- package/dist/commands/hub/credentials.d.ts +21 -0
- package/dist/commands/hub/credentials.js +143 -0
- package/dist/commands/hub/daemon-client.d.ts +27 -0
- package/dist/commands/hub/daemon-client.js +14 -0
- package/dist/commands/hub/deploy-bundle.d.ts +16 -0
- package/dist/commands/hub/deploy-bundle.js +248 -0
- package/dist/commands/hub/deploy.d.ts +25 -4
- package/dist/commands/hub/deploy.js +64 -48
- package/dist/commands/hub/disconnect.d.ts +16 -0
- package/dist/commands/hub/disconnect.js +24 -0
- package/dist/commands/hub/error.d.ts +1 -1
- package/dist/commands/hub/error.js +2 -2
- package/dist/commands/hub/help.d.ts +3 -0
- package/dist/commands/hub/help.js +5 -0
- package/dist/commands/hub/hub-client/index.d.ts +18 -0
- package/dist/commands/hub/hub-client/index.js +88 -0
- package/dist/commands/hub/hub-client/internal/contracts.d.ts +65 -0
- package/dist/commands/hub/hub-client/internal/contracts.js +47 -0
- package/dist/commands/hub/hub-client/internal/problem.d.ts +3 -0
- package/dist/commands/hub/hub-client/internal/problem.js +72 -0
- package/dist/commands/hub/hub-client/internal/transport.d.ts +15 -0
- package/dist/commands/hub/hub-client/internal/transport.js +30 -0
- package/dist/commands/hub/index.d.ts +15 -25
- package/dist/commands/hub/index.js +64 -74
- package/dist/commands/hub/{device-authorization.d.ts → login-flow.d.ts} +12 -15
- package/dist/commands/hub/login-flow.js +78 -0
- package/dist/commands/hub/login.d.ts +21 -0
- package/dist/commands/hub/login.js +34 -0
- package/dist/commands/hub/logout.d.ts +31 -0
- package/dist/commands/hub/logout.js +65 -0
- package/dist/commands/hub/origin.d.ts +2 -0
- package/dist/commands/hub/origin.js +27 -0
- package/dist/commands/hub/projects.d.ts +24 -0
- package/dist/commands/hub/projects.js +49 -0
- package/dist/commands/hub/reporter.d.ts +10 -0
- package/dist/commands/hub/reporter.js +11 -0
- package/dist/commands/hub/status-output.d.ts +13 -0
- package/dist/commands/hub/status-output.js +30 -0
- package/dist/commands/provider/diagnostic.d.ts +12 -0
- package/dist/commands/provider/diagnostic.js +31 -0
- package/dist/commands/provider/index.js +5 -0
- package/dist/commands/schedule/types.d.ts +1 -4
- package/dist/commands/workspace/index.js +10 -0
- package/dist/commands/workspace/rename.d.ts +22 -0
- package/dist/commands/workspace/rename.js +61 -0
- package/dist/output/types.d.ts +1 -1
- package/package.json +4 -4
- package/dist/commands/chat/create.d.ts +0 -9
- package/dist/commands/chat/create.js +0 -23
- package/dist/commands/chat/delete.d.ts +0 -6
- package/dist/commands/chat/delete.js +0 -20
- package/dist/commands/chat/index.d.ts +0 -3
- package/dist/commands/chat/index.js +0 -47
- package/dist/commands/chat/inspect.d.ts +0 -6
- package/dist/commands/chat/inspect.js +0 -20
- package/dist/commands/chat/ls.d.ts +0 -6
- package/dist/commands/chat/ls.js +0 -20
- package/dist/commands/chat/post.d.ts +0 -9
- package/dist/commands/chat/post.js +0 -28
- package/dist/commands/chat/read.d.ts +0 -11
- package/dist/commands/chat/read.js +0 -40
- package/dist/commands/chat/schema.d.ts +0 -36
- package/dist/commands/chat/schema.js +0 -81
- package/dist/commands/chat/shared.d.ts +0 -19
- package/dist/commands/chat/shared.js +0 -118
- package/dist/commands/chat/wait.d.ts +0 -9
- package/dist/commands/chat/wait.js +0 -45
- package/dist/commands/hub/client.d.ts +0 -19
- package/dist/commands/hub/client.js +0 -114
- package/dist/commands/hub/cloud-device-authorization.d.ts +0 -45
- package/dist/commands/hub/cloud-device-authorization.js +0 -92
- package/dist/commands/hub/deploy-input.d.ts +0 -17
- package/dist/commands/hub/deploy-input.js +0 -264
- package/dist/commands/hub/device-authorization.js +0 -87
- package/dist/commands/loop/index.d.ts +0 -3
- package/dist/commands/loop/index.js +0 -18
- package/dist/commands/loop/inspect.d.ts +0 -13
- package/dist/commands/loop/inspect.js +0 -100
- package/dist/commands/loop/logs.d.ts +0 -8
- package/dist/commands/loop/logs.js +0 -69
- package/dist/commands/loop/ls.d.ts +0 -18
- package/dist/commands/loop/ls.js +0 -62
- package/dist/commands/loop/run.d.ts +0 -30
- package/dist/commands/loop/run.js +0 -162
- package/dist/commands/loop/stop.d.ts +0 -15
- package/dist/commands/loop/stop.js +0 -56
- package/dist/commands/loop/types.d.ts +0 -138
- package/dist/commands/loop/types.js +0 -2
|
@@ -1,87 +1,77 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
|
-
import { hostname } from "node:os";
|
|
3
2
|
import { withOutput } from "../../output/index.js";
|
|
4
3
|
import { addJsonAndDaemonHostOptions } from "../../utils/command-options.js";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
4
|
+
import { HubHttpClient } from "./hub-client/index.js";
|
|
5
|
+
import { addHubConnectCommand } from "./connect.js";
|
|
6
|
+
import { PrivateHubCredentialStore } from "./credentials.js";
|
|
7
|
+
import { productionHubDaemonConnection, withHubDaemon, } from "./daemon-client.js";
|
|
7
8
|
import { addHubDeployCommand } from "./deploy.js";
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
{ header: "SCOPES", field: "scopes" },
|
|
20
|
-
{ header: "CONNECTED", field: "connectedAt" },
|
|
21
|
-
{ header: "ERROR", field: "error" },
|
|
22
|
-
{ header: "WARNING", field: "warning" },
|
|
23
|
-
],
|
|
24
|
-
};
|
|
25
|
-
function result(status, warning) {
|
|
9
|
+
import { addHubDisconnectCommand } from "./disconnect.js";
|
|
10
|
+
import { createCliLoginFlow } from "./login-flow.js";
|
|
11
|
+
import { addHubLoginCommand } from "./login.js";
|
|
12
|
+
import { addHubLogoutCommand, productionLogoutPrompt } from "./logout.js";
|
|
13
|
+
import { addHubProjectsCommand } from "./projects.js";
|
|
14
|
+
import { processHubReporter } from "./reporter.js";
|
|
15
|
+
import { hubStatusResult } from "./status-output.js";
|
|
16
|
+
import { addHubResolutionHelp } from "./help.js";
|
|
17
|
+
function productionEnvironment() {
|
|
18
|
+
const env = process.env;
|
|
19
|
+
const hub = new HubHttpClient();
|
|
26
20
|
return {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
error: status.lastError,
|
|
36
|
-
warning,
|
|
37
|
-
},
|
|
38
|
-
],
|
|
39
|
-
schema,
|
|
21
|
+
env,
|
|
22
|
+
credentials: new PrivateHubCredentialStore(env),
|
|
23
|
+
hub,
|
|
24
|
+
login: createCliLoginFlow(hub),
|
|
25
|
+
daemon: productionHubDaemonConnection,
|
|
26
|
+
reporter: processHubReporter,
|
|
27
|
+
cwd: () => process.cwd(),
|
|
28
|
+
...productionLogoutPrompt,
|
|
40
29
|
};
|
|
41
30
|
}
|
|
42
|
-
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
return result((await client.connectHub(url, options.token)).status);
|
|
59
|
-
}
|
|
60
|
-
const existing = (await client.getHubStatus()).status;
|
|
61
|
-
if (existing.state !== "not_connected" && existing.state !== "revoked") {
|
|
62
|
-
throw new Error("This daemon already has a Hub relationship");
|
|
63
|
-
}
|
|
64
|
-
const token = await environment.authorize(url, suggestedDisplayName(environment.displayName()));
|
|
65
|
-
return result((await client.connectHub(url, token)).status);
|
|
66
|
-
});
|
|
67
|
-
}));
|
|
31
|
+
export function createHubCommand(overrides = {}) {
|
|
32
|
+
const environment = { ...productionEnvironment(), ...overrides };
|
|
33
|
+
const hub = addHubResolutionHelp(new Command("hub").description("Manage Paseo Hub"));
|
|
34
|
+
addHubLoginCommand(hub, {
|
|
35
|
+
env: environment.env,
|
|
36
|
+
credentials: environment.credentials,
|
|
37
|
+
flow: environment.login,
|
|
38
|
+
reporter: environment.reporter,
|
|
39
|
+
});
|
|
40
|
+
addHubConnectCommand(hub, {
|
|
41
|
+
env: environment.env,
|
|
42
|
+
credentials: environment.credentials,
|
|
43
|
+
hub: environment.hub,
|
|
44
|
+
daemon: environment.daemon,
|
|
45
|
+
reporter: environment.reporter,
|
|
46
|
+
});
|
|
68
47
|
addJsonAndDaemonHostOptions(hub.command("status")).action(withOutput(async (...args) => {
|
|
69
48
|
const options = args.at(-2);
|
|
70
|
-
return
|
|
49
|
+
return withHubDaemon(environment.daemon, options.host, async (client) => hubStatusResult((await client.getHubStatus()).status));
|
|
71
50
|
}));
|
|
72
|
-
|
|
73
|
-
.
|
|
74
|
-
.
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
51
|
+
addHubDisconnectCommand(hub, {
|
|
52
|
+
daemon: environment.daemon,
|
|
53
|
+
reporter: environment.reporter,
|
|
54
|
+
});
|
|
55
|
+
addHubProjectsCommand(hub, {
|
|
56
|
+
env: environment.env,
|
|
57
|
+
credentials: environment.credentials,
|
|
58
|
+
hub: environment.hub,
|
|
59
|
+
reporter: environment.reporter,
|
|
60
|
+
});
|
|
61
|
+
addHubDeployCommand(hub, {
|
|
62
|
+
env: environment.env,
|
|
63
|
+
credentials: environment.credentials,
|
|
64
|
+
hub: environment.hub,
|
|
65
|
+
reporter: environment.reporter,
|
|
66
|
+
cwd: environment.cwd,
|
|
67
|
+
});
|
|
68
|
+
addHubLogoutCommand(hub, {
|
|
69
|
+
credentials: environment.credentials,
|
|
70
|
+
daemon: environment.daemon,
|
|
71
|
+
isInteractive: environment.isInteractive,
|
|
72
|
+
confirmDisconnect: environment.confirmDisconnect,
|
|
73
|
+
reporter: environment.reporter,
|
|
74
|
+
});
|
|
82
75
|
return hub;
|
|
83
76
|
}
|
|
84
|
-
function suggestedDisplayName(value) {
|
|
85
|
-
return value.trim().slice(0, 100) || "Paseo daemon";
|
|
86
|
-
}
|
|
87
77
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export interface
|
|
1
|
+
import type { HubHttpClient } from "./hub-client/index.js";
|
|
2
|
+
export interface LoginWaiter {
|
|
3
3
|
wait(milliseconds: number): Promise<void>;
|
|
4
4
|
now(): number;
|
|
5
5
|
}
|
|
@@ -17,21 +17,18 @@ export declare class SystemBrowser implements BrowserOpener {
|
|
|
17
17
|
constructor(options?: SystemBrowserOptions);
|
|
18
18
|
open(url: string): Promise<void>;
|
|
19
19
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
interface DeviceAuthorizationWorkflowOptions {
|
|
24
|
-
cloud: CloudDeviceAuthorization;
|
|
25
|
-
waiter: AuthorizationWaiter;
|
|
20
|
+
interface CliLoginFlowOptions {
|
|
21
|
+
hub: Pick<HubHttpClient, "startCliAuthorization" | "pollCliAuthorization">;
|
|
22
|
+
waiter: LoginWaiter;
|
|
26
23
|
browser: BrowserOpener;
|
|
27
|
-
|
|
28
|
-
openBrowser
|
|
24
|
+
instructions(verificationUri: string, userCode: string): void;
|
|
25
|
+
openBrowser: boolean;
|
|
29
26
|
}
|
|
30
|
-
export declare class
|
|
27
|
+
export declare class CliLoginFlow {
|
|
31
28
|
private readonly options;
|
|
32
|
-
constructor(options:
|
|
33
|
-
authorize(
|
|
29
|
+
constructor(options: CliLoginFlowOptions);
|
|
30
|
+
authorize(origin: string): Promise<string>;
|
|
34
31
|
}
|
|
35
|
-
export declare function
|
|
32
|
+
export declare function createCliLoginFlow(hub: HubHttpClient): CliLoginFlow;
|
|
36
33
|
export {};
|
|
37
|
-
//# sourceMappingURL=
|
|
34
|
+
//# sourceMappingURL=login-flow.d.ts.map
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { platform } from "node:os";
|
|
3
|
+
export class SystemBrowser {
|
|
4
|
+
constructor(options = {}) {
|
|
5
|
+
this.hostPlatform = options.hostPlatform ?? platform();
|
|
6
|
+
this.launch = options.launch ?? launchDetached;
|
|
7
|
+
}
|
|
8
|
+
async open(url) {
|
|
9
|
+
if (this.hostPlatform === "win32") {
|
|
10
|
+
await this.launch("rundll32.exe", ["url.dll,FileProtocolHandler", url]);
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
await this.launch(this.hostPlatform === "darwin" ? "open" : "xdg-open", [url]);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export class CliLoginFlow {
|
|
17
|
+
constructor(options) {
|
|
18
|
+
this.options = options;
|
|
19
|
+
}
|
|
20
|
+
async authorize(origin) {
|
|
21
|
+
const authorization = await this.options.hub.startCliAuthorization(origin);
|
|
22
|
+
this.options.instructions(authorization.verificationUri, authorization.userCode);
|
|
23
|
+
if (this.options.openBrowser) {
|
|
24
|
+
await this.options.browser.open(authorization.verificationUriComplete).catch(() => undefined);
|
|
25
|
+
}
|
|
26
|
+
let interval = authorization.interval;
|
|
27
|
+
const expiresAt = Date.parse(authorization.expiresAt);
|
|
28
|
+
while (true) {
|
|
29
|
+
const remaining = expiresAt - this.options.waiter.now();
|
|
30
|
+
if (remaining <= 0)
|
|
31
|
+
throw new Error("Hub CLI login expired");
|
|
32
|
+
await this.options.waiter.wait(Math.min(interval * 1000, remaining));
|
|
33
|
+
const pollLifetime = expiresAt - this.options.waiter.now();
|
|
34
|
+
if (pollLifetime <= 0)
|
|
35
|
+
throw new Error("Hub CLI login expired");
|
|
36
|
+
const outcome = await this.options.hub.pollCliAuthorization(origin, authorization.deviceCode, pollLifetime);
|
|
37
|
+
const credential = approvedCredential(outcome);
|
|
38
|
+
if (credential !== null)
|
|
39
|
+
return credential;
|
|
40
|
+
if (outcome.status === "denied")
|
|
41
|
+
throw new Error("Hub CLI login was denied");
|
|
42
|
+
if (outcome.status === "expired")
|
|
43
|
+
throw new Error("Hub CLI login expired");
|
|
44
|
+
if (outcome.status === "disclosed")
|
|
45
|
+
throw new Error("Hub CLI login was already completed");
|
|
46
|
+
if (outcome.status !== "retry_later")
|
|
47
|
+
interval = outcome.interval;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
export function createCliLoginFlow(hub) {
|
|
52
|
+
return new CliLoginFlow({
|
|
53
|
+
hub,
|
|
54
|
+
waiter: {
|
|
55
|
+
wait: (milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds)),
|
|
56
|
+
now: Date.now,
|
|
57
|
+
},
|
|
58
|
+
browser: new SystemBrowser(),
|
|
59
|
+
instructions(verificationUri, userCode) {
|
|
60
|
+
process.stderr.write(`Open ${verificationUri} and enter code ${userCode}\n`);
|
|
61
|
+
},
|
|
62
|
+
openBrowser: process.stderr.isTTY === true,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
function approvedCredential(outcome) {
|
|
66
|
+
return outcome.status === "authorized" ? outcome.credential : null;
|
|
67
|
+
}
|
|
68
|
+
async function launchDetached(command, args) {
|
|
69
|
+
await new Promise((resolve, reject) => {
|
|
70
|
+
const child = spawn(command, args, { detached: true, shell: false, stdio: "ignore" });
|
|
71
|
+
child.once("spawn", () => {
|
|
72
|
+
child.unref();
|
|
73
|
+
resolve();
|
|
74
|
+
});
|
|
75
|
+
child.once("error", reject);
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=login-flow.js.map
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Command } from "commander";
|
|
2
|
+
import { type SingleResult } from "../../output/index.js";
|
|
3
|
+
import type { HubCredentialStore } from "./credentials.js";
|
|
4
|
+
import type { CliLoginFlow } from "./login-flow.js";
|
|
5
|
+
import { type HubReporter } from "./reporter.js";
|
|
6
|
+
interface HubLoginResult {
|
|
7
|
+
origin: string;
|
|
8
|
+
status: "logged_in";
|
|
9
|
+
}
|
|
10
|
+
interface HubLoginDependencies {
|
|
11
|
+
env: Readonly<Record<string, string | undefined>>;
|
|
12
|
+
credentials: HubCredentialStore;
|
|
13
|
+
flow: Pick<CliLoginFlow, "authorize">;
|
|
14
|
+
reporter: HubReporter;
|
|
15
|
+
}
|
|
16
|
+
export declare function runHubLogin(originInput: string | undefined, options: {
|
|
17
|
+
json?: boolean;
|
|
18
|
+
}, dependencies: HubLoginDependencies): Promise<SingleResult<HubLoginResult>>;
|
|
19
|
+
export declare function addHubLoginCommand(parent: Command, dependencies: HubLoginDependencies): void;
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=login.d.ts.map
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { withOutput } from "../../output/index.js";
|
|
2
|
+
import { addJsonOption } from "../../utils/command-options.js";
|
|
3
|
+
import { resolveHubOrigin } from "./authority.js";
|
|
4
|
+
import { reportHubProgress } from "./reporter.js";
|
|
5
|
+
import { addHubResolutionHelp } from "./help.js";
|
|
6
|
+
const schema = {
|
|
7
|
+
idField: "origin",
|
|
8
|
+
columns: [
|
|
9
|
+
{ header: "HUB", field: "origin" },
|
|
10
|
+
{ header: "STATUS", field: "status" },
|
|
11
|
+
],
|
|
12
|
+
};
|
|
13
|
+
export async function runHubLogin(originInput, options, dependencies) {
|
|
14
|
+
const origin = resolveHubOrigin({
|
|
15
|
+
options: { origin: originInput },
|
|
16
|
+
env: dependencies.env,
|
|
17
|
+
credentials: dependencies.credentials,
|
|
18
|
+
});
|
|
19
|
+
reportHubProgress(dependencies.reporter, options, `Logging in to ${origin}`);
|
|
20
|
+
const credential = await dependencies.flow.authorize(origin);
|
|
21
|
+
dependencies.credentials.save({ origin, credential });
|
|
22
|
+
return { type: "single", data: { origin, status: "logged_in" }, schema };
|
|
23
|
+
}
|
|
24
|
+
export function addHubLoginCommand(parent, dependencies) {
|
|
25
|
+
addJsonOption(addHubResolutionHelp(parent
|
|
26
|
+
.command("login")
|
|
27
|
+
.description("Log in to a Paseo Hub for CLI access")
|
|
28
|
+
.argument("[origin]", "Paseo Hub origin"))).action(withOutput(async (...args) => {
|
|
29
|
+
const origin = args[0];
|
|
30
|
+
const options = args.at(-2);
|
|
31
|
+
return runHubLogin(origin, options, dependencies);
|
|
32
|
+
}));
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=login.js.map
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { Command } from "commander";
|
|
2
|
+
import { type SingleResult } from "../../output/index.js";
|
|
3
|
+
import type { HubCredentialStore } from "./credentials.js";
|
|
4
|
+
import type { HubDaemonConnection } from "./daemon-client.js";
|
|
5
|
+
import { type HubReporter } from "./reporter.js";
|
|
6
|
+
interface HubLogoutResult {
|
|
7
|
+
origin: string | null;
|
|
8
|
+
status: "logged_out" | "not_logged_in";
|
|
9
|
+
daemonDisconnected: boolean;
|
|
10
|
+
}
|
|
11
|
+
interface HubLogoutOptions {
|
|
12
|
+
disconnectDaemon?: boolean;
|
|
13
|
+
force?: boolean;
|
|
14
|
+
host?: string;
|
|
15
|
+
json?: boolean;
|
|
16
|
+
}
|
|
17
|
+
interface HubLogoutDependencies {
|
|
18
|
+
credentials: HubCredentialStore;
|
|
19
|
+
daemon: HubDaemonConnection;
|
|
20
|
+
isInteractive(): boolean;
|
|
21
|
+
confirmDisconnect(origin: string): Promise<boolean>;
|
|
22
|
+
reporter: HubReporter;
|
|
23
|
+
}
|
|
24
|
+
export declare function runHubLogout(options: HubLogoutOptions, dependencies: HubLogoutDependencies): Promise<SingleResult<HubLogoutResult>>;
|
|
25
|
+
export declare function addHubLogoutCommand(parent: Command, dependencies: HubLogoutDependencies): void;
|
|
26
|
+
export declare const productionLogoutPrompt: {
|
|
27
|
+
isInteractive: () => boolean;
|
|
28
|
+
confirmDisconnect(origin: string): Promise<boolean>;
|
|
29
|
+
};
|
|
30
|
+
export {};
|
|
31
|
+
//# sourceMappingURL=logout.d.ts.map
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { confirm, isCancel } from "@clack/prompts";
|
|
2
|
+
import { withOutput } from "../../output/index.js";
|
|
3
|
+
import { addJsonAndDaemonHostOptions } from "../../utils/command-options.js";
|
|
4
|
+
import { withHubDaemon } from "./daemon-client.js";
|
|
5
|
+
import { reportHubProgress } from "./reporter.js";
|
|
6
|
+
const schema = {
|
|
7
|
+
idField: "status",
|
|
8
|
+
columns: [
|
|
9
|
+
{ header: "HUB", field: "origin" },
|
|
10
|
+
{ header: "STATUS", field: "status" },
|
|
11
|
+
{ header: "DAEMON DISCONNECTED", field: "daemonDisconnected" },
|
|
12
|
+
],
|
|
13
|
+
};
|
|
14
|
+
export async function runHubLogout(options, dependencies) {
|
|
15
|
+
const active = dependencies.credentials.active();
|
|
16
|
+
if (active === null) {
|
|
17
|
+
return logoutResult({ origin: null, status: "not_logged_in", daemonDisconnected: false });
|
|
18
|
+
}
|
|
19
|
+
reportHubProgress(dependencies.reporter, options, `Logging out of ${active.origin}`);
|
|
20
|
+
const mayPrompt = options.json !== true && dependencies.isInteractive();
|
|
21
|
+
let daemonStatus = null;
|
|
22
|
+
const shouldInspectDaemon = options.disconnectDaemon === true || mayPrompt;
|
|
23
|
+
if (shouldInspectDaemon) {
|
|
24
|
+
daemonStatus = await withHubDaemon(dependencies.daemon, options.host, async (daemon) => daemon.getHubStatus().then((response) => response.status));
|
|
25
|
+
}
|
|
26
|
+
const sameHub = daemonStatus?.hubOrigin === active.origin;
|
|
27
|
+
let shouldDisconnect = options.disconnectDaemon === true && sameHub;
|
|
28
|
+
if (options.disconnectDaemon !== true && mayPrompt && sameHub) {
|
|
29
|
+
shouldDisconnect = await dependencies.confirmDisconnect(active.origin);
|
|
30
|
+
}
|
|
31
|
+
if (!shouldDisconnect) {
|
|
32
|
+
dependencies.credentials.logoutActive();
|
|
33
|
+
return logoutResult({ origin: active.origin, status: "logged_out", daemonDisconnected: false });
|
|
34
|
+
}
|
|
35
|
+
reportHubProgress(dependencies.reporter, options, `Disconnecting this daemon from ${active.origin}`);
|
|
36
|
+
await withHubDaemon(dependencies.daemon, options.host, async (daemon) => {
|
|
37
|
+
await daemon.disconnectHub(options.force ?? false);
|
|
38
|
+
});
|
|
39
|
+
dependencies.credentials.logoutActive();
|
|
40
|
+
return logoutResult({ origin: active.origin, status: "logged_out", daemonDisconnected: true });
|
|
41
|
+
}
|
|
42
|
+
export function addHubLogoutCommand(parent, dependencies) {
|
|
43
|
+
addJsonAndDaemonHostOptions(parent
|
|
44
|
+
.command("logout")
|
|
45
|
+
.description("Remove the active stored Hub CLI login")
|
|
46
|
+
.option("--disconnect-daemon", "Also disconnect a daemon related to the same Hub")
|
|
47
|
+
.option("--force", "Remove daemon authority even if Hub is offline")).action(withOutput(async (...args) => {
|
|
48
|
+
const options = args.at(-2);
|
|
49
|
+
return runHubLogout(options, dependencies);
|
|
50
|
+
}));
|
|
51
|
+
}
|
|
52
|
+
export const productionLogoutPrompt = {
|
|
53
|
+
isInteractive: () => Boolean(process.stdin.isTTY && process.stdout.isTTY),
|
|
54
|
+
async confirmDisconnect(origin) {
|
|
55
|
+
const answer = await confirm({
|
|
56
|
+
message: `Disconnect this daemon from ${origin}?`,
|
|
57
|
+
initialValue: false,
|
|
58
|
+
});
|
|
59
|
+
return !isCancel(answer) && answer;
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
function logoutResult(data) {
|
|
63
|
+
return { type: "single", data, schema };
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=logout.js.map
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { HubCommandError } from "./error.js";
|
|
2
|
+
export function normalizeHubOrigin(value) {
|
|
3
|
+
let url;
|
|
4
|
+
try {
|
|
5
|
+
url = new URL(value);
|
|
6
|
+
}
|
|
7
|
+
catch {
|
|
8
|
+
throw invalidHubOrigin();
|
|
9
|
+
}
|
|
10
|
+
if (!["http:", "https:"].includes(url.protocol) ||
|
|
11
|
+
(url.protocol === "http:" && !isLoopbackHostname(url.hostname)) ||
|
|
12
|
+
url.username ||
|
|
13
|
+
url.password ||
|
|
14
|
+
url.pathname !== "/" ||
|
|
15
|
+
url.search ||
|
|
16
|
+
url.hash) {
|
|
17
|
+
throw invalidHubOrigin();
|
|
18
|
+
}
|
|
19
|
+
return url.origin;
|
|
20
|
+
}
|
|
21
|
+
function isLoopbackHostname(hostname) {
|
|
22
|
+
return hostname === "localhost" || hostname === "127.0.0.1" || hostname === "[::1]";
|
|
23
|
+
}
|
|
24
|
+
function invalidHubOrigin() {
|
|
25
|
+
return new HubCommandError("HUB_INVALID_ORIGIN", "Hub URL must be an HTTPS origin without credentials, path, query, or hash. HTTP is allowed only for localhost, 127.0.0.1, or [::1].");
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=origin.js.map
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Command } from "commander";
|
|
2
|
+
import { type SingleResult } from "../../output/index.js";
|
|
3
|
+
import type { HubHttpClient, HubProject } from "./hub-client/index.js";
|
|
4
|
+
import type { HubCredentialStore } from "./credentials.js";
|
|
5
|
+
import { type HubReporter } from "./reporter.js";
|
|
6
|
+
interface HubProjectsResult {
|
|
7
|
+
origin: string;
|
|
8
|
+
projects: HubProject[];
|
|
9
|
+
}
|
|
10
|
+
export interface HubProjectsOptions {
|
|
11
|
+
hub?: string;
|
|
12
|
+
apiKey?: string;
|
|
13
|
+
json?: boolean;
|
|
14
|
+
}
|
|
15
|
+
interface HubProjectsDependencies {
|
|
16
|
+
env: Readonly<Record<string, string | undefined>>;
|
|
17
|
+
credentials: HubCredentialStore;
|
|
18
|
+
hub: Pick<HubHttpClient, "listProjects">;
|
|
19
|
+
reporter: HubReporter;
|
|
20
|
+
}
|
|
21
|
+
export declare function runHubProjects(options: HubProjectsOptions, dependencies: HubProjectsDependencies): Promise<SingleResult<HubProjectsResult>>;
|
|
22
|
+
export declare function addHubProjectsCommand(parent: Command, dependencies: HubProjectsDependencies): void;
|
|
23
|
+
export {};
|
|
24
|
+
//# sourceMappingURL=projects.d.ts.map
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { render, withOutput } from "../../output/index.js";
|
|
2
|
+
import { addJsonOption } from "../../utils/command-options.js";
|
|
3
|
+
import { resolveHubCredential, resolveHubOrigin } from "./authority.js";
|
|
4
|
+
import { reportHubProgress } from "./reporter.js";
|
|
5
|
+
import { addHubResolutionHelp } from "./help.js";
|
|
6
|
+
const projectSchema = {
|
|
7
|
+
idField: "id",
|
|
8
|
+
columns: [
|
|
9
|
+
{ header: "SLUG", field: "slug" },
|
|
10
|
+
{ header: "NAME", field: "name" },
|
|
11
|
+
{ header: "ID", field: "id" },
|
|
12
|
+
{ header: "HUB", field: "origin" },
|
|
13
|
+
],
|
|
14
|
+
};
|
|
15
|
+
const schema = {
|
|
16
|
+
idField: "origin",
|
|
17
|
+
columns: [
|
|
18
|
+
{ header: "HUB", field: "origin" },
|
|
19
|
+
{ header: "PROJECTS", field: (result) => result.projects.length },
|
|
20
|
+
],
|
|
21
|
+
renderHuman(result, options) {
|
|
22
|
+
const results = result.type === "single" ? [result.data] : result.data;
|
|
23
|
+
const data = results.flatMap((entry) => entry.projects.map((project) => ({ ...project, origin: entry.origin })));
|
|
24
|
+
return render({ type: "list", data, schema: projectSchema }, options);
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
export async function runHubProjects(options, dependencies) {
|
|
28
|
+
const resolution = {
|
|
29
|
+
options: { origin: options.hub, apiKey: options.apiKey },
|
|
30
|
+
env: dependencies.env,
|
|
31
|
+
credentials: dependencies.credentials,
|
|
32
|
+
};
|
|
33
|
+
const origin = resolveHubOrigin(resolution);
|
|
34
|
+
reportHubProgress(dependencies.reporter, options, `Listing projects from ${origin}`);
|
|
35
|
+
const credential = resolveHubCredential({ ...resolution, origin });
|
|
36
|
+
const projects = await dependencies.hub.listProjects(origin, credential);
|
|
37
|
+
return { type: "single", data: { origin, projects }, schema };
|
|
38
|
+
}
|
|
39
|
+
export function addHubProjectsCommand(parent, dependencies) {
|
|
40
|
+
addJsonOption(addHubResolutionHelp(parent
|
|
41
|
+
.command("projects")
|
|
42
|
+
.description("List projects for the authenticated Hub organization")
|
|
43
|
+
.option("--hub <origin>", "Paseo Hub origin")
|
|
44
|
+
.option("--api-key <secret>", "Organization API key"))).action(withOutput(async (...args) => {
|
|
45
|
+
const options = args.at(-2);
|
|
46
|
+
return runHubProjects(options, dependencies);
|
|
47
|
+
}));
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=projects.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface HubReporter {
|
|
2
|
+
progress(message: string): void;
|
|
3
|
+
}
|
|
4
|
+
export declare const processHubReporter: HubReporter;
|
|
5
|
+
interface HubReportOptions {
|
|
6
|
+
json?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare function reportHubProgress(reporter: HubReporter, options: HubReportOptions, message: string): void;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=reporter.d.ts.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export const processHubReporter = {
|
|
2
|
+
progress(message) {
|
|
3
|
+
process.stderr.write(`${message}\n`);
|
|
4
|
+
},
|
|
5
|
+
};
|
|
6
|
+
export function reportHubProgress(reporter, options, message) {
|
|
7
|
+
if (options.json === true)
|
|
8
|
+
return;
|
|
9
|
+
reporter.progress(message);
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=reporter.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ListResult } from "../../output/index.js";
|
|
2
|
+
import type { HubStatus } from "./daemon-client.js";
|
|
3
|
+
export interface HubRow {
|
|
4
|
+
state: string;
|
|
5
|
+
daemonId: string | null;
|
|
6
|
+
hub: string | null;
|
|
7
|
+
scopes: string;
|
|
8
|
+
connectedAt: string | null;
|
|
9
|
+
error: string | null;
|
|
10
|
+
warning?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function hubStatusResult(status: HubStatus, warning?: string, reportedHubOrigin?: string | null): ListResult<HubRow>;
|
|
13
|
+
//# sourceMappingURL=status-output.d.ts.map
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
const schema = {
|
|
2
|
+
idField: "state",
|
|
3
|
+
columns: [
|
|
4
|
+
{ header: "STATE", field: "state" },
|
|
5
|
+
{ header: "HUB", field: "hub" },
|
|
6
|
+
{ header: "DAEMON", field: "daemonId" },
|
|
7
|
+
{ header: "SCOPES", field: "scopes" },
|
|
8
|
+
{ header: "CONNECTED", field: "connectedAt" },
|
|
9
|
+
{ header: "ERROR", field: "error" },
|
|
10
|
+
{ header: "WARNING", field: "warning" },
|
|
11
|
+
],
|
|
12
|
+
};
|
|
13
|
+
export function hubStatusResult(status, warning, reportedHubOrigin = status.hubOrigin) {
|
|
14
|
+
return {
|
|
15
|
+
type: "list",
|
|
16
|
+
data: [
|
|
17
|
+
{
|
|
18
|
+
state: status.state,
|
|
19
|
+
daemonId: status.daemonId,
|
|
20
|
+
hub: reportedHubOrigin,
|
|
21
|
+
scopes: status.scopes.join(", "),
|
|
22
|
+
connectedAt: status.connectedAt,
|
|
23
|
+
error: status.lastError,
|
|
24
|
+
warning,
|
|
25
|
+
},
|
|
26
|
+
],
|
|
27
|
+
schema,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=status-output.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Command } from "commander";
|
|
2
|
+
import type { CommandOptions, OutputSchema, SingleResult } from "../../output/index.js";
|
|
3
|
+
export interface ProviderDiagnosticResult {
|
|
4
|
+
provider: string;
|
|
5
|
+
diagnostic: string;
|
|
6
|
+
}
|
|
7
|
+
export declare const providerDiagnosticSchema: OutputSchema<ProviderDiagnosticResult>;
|
|
8
|
+
export interface ProviderDiagnosticOptions extends CommandOptions {
|
|
9
|
+
host?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function runDiagnosticCommand(provider: string, options: ProviderDiagnosticOptions, _command: Command): Promise<SingleResult<ProviderDiagnosticResult>>;
|
|
12
|
+
//# sourceMappingURL=diagnostic.d.ts.map
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { connectToDaemon } from "../../utils/client.js";
|
|
2
|
+
export const providerDiagnosticSchema = {
|
|
3
|
+
idField: "provider",
|
|
4
|
+
columns: [
|
|
5
|
+
{ header: "PROVIDER", field: "provider" },
|
|
6
|
+
{ header: "DIAGNOSTIC", field: "diagnostic" },
|
|
7
|
+
],
|
|
8
|
+
renderHuman(result) {
|
|
9
|
+
if (result.type === "single")
|
|
10
|
+
return result.data.diagnostic;
|
|
11
|
+
return result.data.map((entry) => entry.diagnostic).join("\n\n");
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
export async function runDiagnosticCommand(provider, options, _command) {
|
|
15
|
+
const client = await connectToDaemon({ host: options.host });
|
|
16
|
+
try {
|
|
17
|
+
const result = await client.getProviderDiagnostic(provider.trim().toLowerCase());
|
|
18
|
+
return {
|
|
19
|
+
type: "single",
|
|
20
|
+
data: {
|
|
21
|
+
provider: result.provider,
|
|
22
|
+
diagnostic: result.diagnostic,
|
|
23
|
+
},
|
|
24
|
+
schema: providerDiagnosticSchema,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
finally {
|
|
28
|
+
await client.close();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=diagnostic.js.map
|