@tonbo/cli 0.0.1 → 0.0.2

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.
@@ -4,7 +4,8 @@ export declare class AuthClient {
4
4
  private readonly credentials;
5
5
  private readonly fetcher;
6
6
  private readonly accountOrigin;
7
- constructor(credentials: CredentialStore, fetcher: typeof fetch, accountOrigin?: string);
7
+ private readonly browserOpener;
8
+ constructor(credentials: CredentialStore, fetcher: typeof fetch, accountOrigin?: string, browserOpener?: (url: string) => Promise<void>);
8
9
  accessToken(): Promise<string>;
9
10
  login(): Promise<OAuthTokenSet>;
10
11
  private config;
package/dist/src/auth.js CHANGED
@@ -21,10 +21,12 @@ export class AuthClient {
21
21
  credentials;
22
22
  fetcher;
23
23
  accountOrigin;
24
- constructor(credentials, fetcher, accountOrigin = "https://tonbo.dev") {
24
+ browserOpener;
25
+ constructor(credentials, fetcher, accountOrigin = "https://tonbo.dev", browserOpener = openBrowser) {
25
26
  this.credentials = credentials;
26
27
  this.fetcher = fetcher;
27
28
  this.accountOrigin = accountOrigin;
29
+ this.browserOpener = browserOpener;
28
30
  }
29
31
  async accessToken() {
30
32
  const injected = process.env.TONBO_ACCESS_TOKEN?.trim();
@@ -70,7 +72,7 @@ export class AuthClient {
70
72
  scope: "openid profile email",
71
73
  state,
72
74
  }).toString();
73
- const code = await this.listenForCode(state, () => openBrowser(authorization.toString()));
75
+ const code = await this.listenForCode(state, () => this.browserOpener(authorization.toString()));
74
76
  const tokens = withAbsoluteExpiry(await this.exchange(config.token_endpoint, new URLSearchParams({
75
77
  client_id: config.client_id,
76
78
  code,
@@ -99,11 +101,20 @@ export class AuthClient {
99
101
  return;
100
102
  settled = true;
101
103
  clearTimeout(timeout);
102
- server.close();
103
- if ("code" in result)
104
- resolve(result.code);
105
- else
106
- reject(result.error);
104
+ const complete = (closeError) => {
105
+ if (closeError)
106
+ reject(closeError);
107
+ else if ("code" in result)
108
+ resolve(result.code);
109
+ else
110
+ reject(result.error);
111
+ };
112
+ if (!server.listening) {
113
+ complete();
114
+ return;
115
+ }
116
+ server.close(complete);
117
+ server.closeIdleConnections();
107
118
  };
108
119
  const timeout = setTimeout(() => {
109
120
  finish({ error: new Error("Timed out waiting for browser login.") });
@@ -113,8 +124,7 @@ export class AuthClient {
113
124
  const code = url.searchParams.get("code");
114
125
  const oauthError = url.searchParams.get("error_description") ?? url.searchParams.get("error");
115
126
  if (oauthError) {
116
- respond(response, "denied");
117
- finish({ error: new Error(oauthError) });
127
+ respond(response, "denied", () => finish({ error: new Error(oauthError) }));
118
128
  return;
119
129
  }
120
130
  if (url.pathname !== "/callback" ||
@@ -123,8 +133,7 @@ export class AuthClient {
123
133
  respond(response, "invalid");
124
134
  return;
125
135
  }
126
- respond(response, "complete");
127
- finish({ code });
136
+ respond(response, "complete", () => finish({ code }));
128
137
  });
129
138
  server.once("error", (error) => finish({ error }));
130
139
  server.listen(17655, "localhost", () => void ready().catch((error) => finish({
@@ -133,9 +142,11 @@ export class AuthClient {
133
142
  });
134
143
  }
135
144
  }
136
- function respond(response, outcome) {
145
+ function respond(response, outcome, finished) {
137
146
  const page = callbackResponse(outcome);
138
- response.writeHead(page.status, page.headers);
147
+ if (finished)
148
+ response.once("finish", finished);
149
+ response.writeHead(page.status, { ...page.headers, connection: "close" });
139
150
  response.end(page.body);
140
151
  }
141
152
  async function openBrowser(url) {
@@ -42,11 +42,7 @@ export async function loginCommand(deps) {
42
42
  const keys = await readDefaultSshPublicKeys();
43
43
  for (const key of keys)
44
44
  await deps.api.registerSshKey(oauthToken, key);
45
- deps.output({
46
- message: keys.length
47
- ? `Logged in to Tonbo and registered ${keys.length} SSH key${keys.length === 1 ? "" : "s"}.`
48
- : "Logged in to Tonbo. No default SSH public key was found; run `tonbo ssh-key add <path.pub>` before using native SSH.",
49
- });
45
+ deps.output({ message: "Logged in to Tonbo." });
50
46
  }
51
47
  export async function sshKeyAddCommand(deps, path) {
52
48
  const key = await readSshPublicKey(path);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tonbo/cli",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "description": "Deploy one persistent Agent per Project from the command line.",
5
5
  "homepage": "https://tonbo.dev",
6
6
  "bugs": {