@alchemy/cli 0.6.2 → 0.7.0-alpha.11
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 +114 -94
- package/dist/{auth-S4DTOWW3.js → auth-FQFFNNZZ.js} +10 -8
- package/dist/auth-ZME2NTXG.js +16 -0
- package/dist/{chunk-TK3HZ5UT.js → chunk-3FDXTEBV.js} +3 -3
- package/dist/{chunk-ATX65U7J.js → chunk-A6BWLRFV.js} +572 -41
- package/dist/{chunk-NBDWF4ZQ.js → chunk-AFD4Y42F.js} +32 -22
- package/dist/{chunk-FFMNT74F.js → chunk-EKBSQAEG.js} +125 -76
- package/dist/chunk-HGZTGSXO.js +261 -0
- package/dist/{chunk-KDMIWPZH.js → chunk-JMDBEC5L.js} +1 -1
- package/dist/{chunk-UMKDYHMO.js → chunk-KJ5VM7FE.js} +54 -99
- package/dist/{chunk-56ZVYB4G.js → chunk-OLVYWGY6.js} +263 -222
- package/dist/chunk-PXPURTNF.js +64 -0
- package/dist/errors-VUVL3B2E.js +54 -0
- package/dist/index.js +6727 -2168
- package/dist/{interactive-UGD7GYJM.js → interactive-ECDBQ2E6.js} +56 -61
- package/dist/{onboarding-IP4R44EQ.js → onboarding-ATR4YYG3.js} +14 -11
- package/dist/resolve-O64VTY3W.js +50 -0
- package/package.json +11 -6
- package/scripts/postinstall.cjs +69 -1
- package/dist/auth-QB3BA7AN.js +0 -17
- package/dist/chunk-BAAQ7ELR.js +0 -143
- package/dist/chunk-JQRGILIS.js +0 -53
- package/dist/chunk-T5Z2GJUX.js +0 -331
- package/dist/credential-storage-T6FFW7DG.js +0 -14
- package/dist/resolve-HXKHDOJZ.js +0 -31
|
@@ -1,26 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
if(process.argv.includes("--no-color"))process.env.NO_COLOR="1";
|
|
3
3
|
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
revokeToken,
|
|
9
|
-
waitForCallback
|
|
10
|
-
} from "./chunk-FFMNT74F.js";
|
|
4
|
+
completeLogin,
|
|
5
|
+
prepareLogin,
|
|
6
|
+
revokeToken
|
|
7
|
+
} from "./chunk-EKBSQAEG.js";
|
|
11
8
|
import {
|
|
12
9
|
isInteractiveAllowed
|
|
13
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-JMDBEC5L.js";
|
|
14
11
|
import {
|
|
15
12
|
AdminClient,
|
|
16
13
|
resolveAuthToken
|
|
17
|
-
} from "./chunk-
|
|
18
|
-
import {
|
|
19
|
-
deleteCredentials,
|
|
20
|
-
getCredentials,
|
|
21
|
-
getStorageBackend,
|
|
22
|
-
saveCredentials
|
|
23
|
-
} from "./chunk-JQRGILIS.js";
|
|
14
|
+
} from "./chunk-A6BWLRFV.js";
|
|
24
15
|
import {
|
|
25
16
|
bold,
|
|
26
17
|
brand,
|
|
@@ -29,12 +20,13 @@ import {
|
|
|
29
20
|
promptAutocomplete,
|
|
30
21
|
promptText,
|
|
31
22
|
withSpinner
|
|
32
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-AFD4Y42F.js";
|
|
33
24
|
import {
|
|
25
|
+
configPath,
|
|
34
26
|
load,
|
|
35
27
|
maskIf,
|
|
36
28
|
save
|
|
37
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-HGZTGSXO.js";
|
|
38
30
|
import {
|
|
39
31
|
CLIError,
|
|
40
32
|
ErrorCode,
|
|
@@ -42,7 +34,7 @@ import {
|
|
|
42
34
|
exitWithError,
|
|
43
35
|
isJSONMode,
|
|
44
36
|
printHuman
|
|
45
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-OLVYWGY6.js";
|
|
46
38
|
|
|
47
39
|
// src/commands/auth.ts
|
|
48
40
|
function registerAuth(program) {
|
|
@@ -51,7 +43,7 @@ function registerAuth(program) {
|
|
|
51
43
|
const yes = opts.yes || cmd.opts().yes;
|
|
52
44
|
try {
|
|
53
45
|
if (!opts.force) {
|
|
54
|
-
const existing =
|
|
46
|
+
const existing = resolveAuthToken();
|
|
55
47
|
if (existing) {
|
|
56
48
|
printHuman(
|
|
57
49
|
` ${green("\u2713")} Already authenticated
|
|
@@ -64,108 +56,79 @@ function registerAuth(program) {
|
|
|
64
56
|
}
|
|
65
57
|
}
|
|
66
58
|
if (opts.force) {
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
if (cfg2.auth_token) {
|
|
72
|
-
await revokeToken(cfg2.auth_token);
|
|
73
|
-
save({ ...cfg2, auth_token: void 0, auth_token_expires_at: void 0 });
|
|
74
|
-
}
|
|
75
|
-
} else {
|
|
76
|
-
await revokeToken(tokenToRevoke);
|
|
59
|
+
const cfg2 = load();
|
|
60
|
+
if (cfg2.auth_token) {
|
|
61
|
+
await revokeToken(cfg2.auth_token);
|
|
62
|
+
save({ ...cfg2, auth_token: void 0, auth_token_expires_at: void 0 });
|
|
77
63
|
}
|
|
78
|
-
await deleteCredentials();
|
|
79
64
|
}
|
|
80
|
-
const prepared =
|
|
81
|
-
const callbackPromise = waitForCallback(AUTH_PORT);
|
|
65
|
+
const prepared = prepareLogin();
|
|
82
66
|
if (!isJSONMode()) {
|
|
83
67
|
console.log("");
|
|
84
68
|
console.log(` ${brand("\u25C6")} ${bold("Alchemy Authentication")}`);
|
|
85
69
|
console.log(` ${dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")}`);
|
|
86
70
|
console.log("");
|
|
87
|
-
console.log(` ${dim(prepared.
|
|
71
|
+
console.log(` ${dim(prepared.loginUrl)}`);
|
|
88
72
|
console.log("");
|
|
89
73
|
}
|
|
90
|
-
|
|
74
|
+
const promptAbort = new AbortController();
|
|
75
|
+
let earlyAuth = false;
|
|
76
|
+
prepared.callbackPromise.then(() => {
|
|
77
|
+
earlyAuth = true;
|
|
78
|
+
promptAbort.abort();
|
|
79
|
+
}).catch(() => {
|
|
80
|
+
});
|
|
91
81
|
if (!yes && !isJSONMode() && isInteractiveAllowed(program)) {
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
if (promptResult !== "callback_received") {
|
|
101
|
-
if (!isJSONMode()) {
|
|
102
|
-
console.log(` Opening browser to log in...`);
|
|
103
|
-
console.log(` ${dim("Waiting for authentication...")}`);
|
|
104
|
-
}
|
|
105
|
-
openBrowser(prepared.authorizeUrl);
|
|
106
|
-
browserOpened = true;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
if (!browserOpened && yes) {
|
|
110
|
-
if (!isJSONMode()) {
|
|
111
|
-
console.log(` Opening browser to log in...`);
|
|
112
|
-
console.log(` ${dim("Waiting for authentication...")}`);
|
|
82
|
+
const answer = await promptText({
|
|
83
|
+
message: "Press Enter to open browser, or paste the link above to authenticate",
|
|
84
|
+
cancelMessage: "Login cancelled.",
|
|
85
|
+
abortSignal: promptAbort.signal
|
|
86
|
+
});
|
|
87
|
+
if (answer === null) {
|
|
88
|
+
prepared.cancel();
|
|
89
|
+
return;
|
|
113
90
|
}
|
|
114
|
-
openBrowser(prepared.authorizeUrl);
|
|
115
91
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
throw new Error("OAuth state mismatch. Authentication aborted.");
|
|
120
|
-
}
|
|
121
|
-
let result;
|
|
122
|
-
try {
|
|
123
|
-
result = await exchangeCodeForToken(callback.code, AUTH_PORT, {
|
|
124
|
-
codeVerifier: prepared.codeVerifier
|
|
125
|
-
});
|
|
126
|
-
callback.sendSuccess();
|
|
127
|
-
} catch (err) {
|
|
128
|
-
callback.sendError("Failed to complete authentication. Please try again.");
|
|
129
|
-
throw err;
|
|
92
|
+
if (!earlyAuth && !isJSONMode()) {
|
|
93
|
+
console.log(` Opening browser to log in...`);
|
|
94
|
+
console.log(` ${dim("Waiting for authentication...")}`);
|
|
130
95
|
}
|
|
131
|
-
await
|
|
96
|
+
const result = await completeLogin(prepared, {
|
|
97
|
+
skipBrowserOpen: earlyAuth
|
|
98
|
+
});
|
|
99
|
+
const cfg = load();
|
|
100
|
+
const hasConfiguredApp = Boolean(cfg.app);
|
|
101
|
+
save({
|
|
102
|
+
...cfg,
|
|
132
103
|
auth_token: result.token,
|
|
133
104
|
auth_token_expires_at: result.expiresAt
|
|
134
105
|
});
|
|
135
|
-
const cfg = load();
|
|
136
|
-
if (cfg.auth_token) {
|
|
137
|
-
save({ ...cfg, auth_token: void 0, auth_token_expires_at: void 0 });
|
|
138
|
-
}
|
|
139
106
|
const expiresAt = result.expiresAt;
|
|
140
|
-
const backend = await getStorageBackend();
|
|
141
107
|
printHuman(
|
|
142
108
|
` ${green("\u2713")} Logged in successfully
|
|
143
|
-
${dim("
|
|
109
|
+
${dim("Token saved to")} ${configPath()}
|
|
144
110
|
${dim("Expires:")} ${expiresAt}
|
|
145
111
|
`,
|
|
146
112
|
{
|
|
147
113
|
status: "authenticated",
|
|
148
114
|
expiresAt,
|
|
149
|
-
|
|
115
|
+
configPath: configPath()
|
|
150
116
|
}
|
|
151
117
|
);
|
|
152
|
-
if (isInteractiveAllowed(program)) {
|
|
118
|
+
if (isInteractiveAllowed(program) && !hasConfiguredApp) {
|
|
153
119
|
await selectAppAfterAuth(result.token);
|
|
154
120
|
}
|
|
155
|
-
process.exit(0);
|
|
156
121
|
} catch (err) {
|
|
157
122
|
exitWithError(
|
|
158
123
|
err instanceof CLIError ? err : new CLIError(ErrorCode.AUTH_REQUIRED, String(err.message))
|
|
159
124
|
);
|
|
160
125
|
}
|
|
161
126
|
});
|
|
162
|
-
cmd.command("status").description("Show current authentication status").action(
|
|
127
|
+
cmd.command("status").description("Show current authentication status").action(() => {
|
|
163
128
|
try {
|
|
164
|
-
const creds = await getCredentials();
|
|
165
129
|
const cfg = load();
|
|
166
|
-
const validToken =
|
|
167
|
-
|
|
168
|
-
if (!hasToken) {
|
|
130
|
+
const validToken = resolveAuthToken(cfg);
|
|
131
|
+
if (!cfg.auth_token) {
|
|
169
132
|
printHuman(
|
|
170
133
|
` ${dim("Not authenticated. Run")} alchemy auth ${dim("to log in.")}
|
|
171
134
|
`,
|
|
@@ -181,20 +144,15 @@ function registerAuth(program) {
|
|
|
181
144
|
);
|
|
182
145
|
return;
|
|
183
146
|
}
|
|
184
|
-
const expiresAt = creds?.auth_token_expires_at || cfg.auth_token_expires_at || "unknown";
|
|
185
|
-
const backend = await getStorageBackend();
|
|
186
|
-
const storedIn = creds?.auth_token ? backend : "config file (legacy)";
|
|
187
147
|
printHuman(
|
|
188
148
|
` ${green("\u2713")} Authenticated
|
|
189
149
|
${dim("Token:")} ${maskIf(validToken)}
|
|
190
|
-
${dim("
|
|
191
|
-
${dim("Expires:")} ${expiresAt}
|
|
150
|
+
${dim("Expires:")} ${cfg.auth_token_expires_at || "unknown"}
|
|
192
151
|
`,
|
|
193
152
|
{
|
|
194
153
|
authenticated: true,
|
|
195
154
|
expired: false,
|
|
196
|
-
expiresAt
|
|
197
|
-
storageBackend: storedIn
|
|
155
|
+
expiresAt: cfg.auth_token_expires_at
|
|
198
156
|
}
|
|
199
157
|
);
|
|
200
158
|
} catch (err) {
|
|
@@ -203,17 +161,14 @@ function registerAuth(program) {
|
|
|
203
161
|
});
|
|
204
162
|
cmd.command("logout").description("Clear saved authentication token").action(async () => {
|
|
205
163
|
try {
|
|
206
|
-
const creds = await getCredentials();
|
|
207
164
|
const cfg = load();
|
|
208
|
-
const activeToken = creds?.auth_token || cfg.auth_token;
|
|
209
165
|
let revokeResult;
|
|
210
|
-
if (
|
|
211
|
-
revokeResult = await revokeToken(
|
|
166
|
+
if (cfg.auth_token) {
|
|
167
|
+
revokeResult = await revokeToken(cfg.auth_token);
|
|
212
168
|
}
|
|
213
|
-
|
|
214
|
-
const { auth_token: _, auth_token_expires_at: __, app: ___, ...rest } = cfg;
|
|
169
|
+
const { auth_token: _, auth_token_expires_at: __, ...rest } = cfg;
|
|
215
170
|
save(rest);
|
|
216
|
-
if (!
|
|
171
|
+
if (!cfg.auth_token) {
|
|
217
172
|
printHuman(
|
|
218
173
|
` ${dim("No active session.")}
|
|
219
174
|
`,
|