microgit-cli 0.0.0-stage → 0.1.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.
Files changed (42) hide show
  1. package/README.md +257 -2
  2. package/package.json +26 -4
  3. package/src/api/index.js +111 -0
  4. package/src/api/index.js.map +1 -0
  5. package/src/cli/index.js +32 -0
  6. package/src/cli/index.js.map +1 -0
  7. package/src/cli/repl.js +312 -0
  8. package/src/cli/repl.js.map +1 -0
  9. package/src/commands/auth.js +305 -0
  10. package/src/commands/auth.js.map +1 -0
  11. package/src/commands/config.js +91 -0
  12. package/src/commands/config.js.map +1 -0
  13. package/src/commands/git.js +159 -0
  14. package/src/commands/git.js.map +1 -0
  15. package/src/commands/registry.js +139 -0
  16. package/src/commands/registry.js.map +1 -0
  17. package/src/commands/repos.js +256 -0
  18. package/src/commands/repos.js.map +1 -0
  19. package/src/config/index.js +124 -0
  20. package/src/config/index.js.map +1 -0
  21. package/src/config/settings.js +34 -0
  22. package/src/config/settings.js.map +1 -0
  23. package/src/error/index.js +14 -0
  24. package/src/error/index.js.map +1 -0
  25. package/src/git/index.js +163 -0
  26. package/src/git/index.js.map +1 -0
  27. package/src/help/index.js +52 -0
  28. package/src/help/index.js.map +1 -0
  29. package/src/index.js +9 -0
  30. package/src/index.js.map +1 -0
  31. package/src/theme/banner.js +44 -0
  32. package/src/theme/banner.js.map +1 -0
  33. package/src/theme/index.js +5 -0
  34. package/src/theme/index.js.map +1 -0
  35. package/src/theme/logo.js +36 -0
  36. package/src/theme/logo.js.map +1 -0
  37. package/src/theme/palette.js +32 -0
  38. package/src/theme/palette.js.map +1 -0
  39. package/src/ui/index.js +100 -0
  40. package/src/ui/index.js.map +1 -0
  41. package/src/util/index.js +30 -0
  42. package/src/util/index.js.map +1 -0
@@ -0,0 +1,312 @@
1
+ import fs from 'node:fs';
2
+ import os from 'node:os';
3
+ import path from 'node:path';
4
+ import readline from 'node:readline';
5
+ import { configFilePath, loadConfig } from '../config/index.js';
6
+ import { errorMessage } from '../error/index.js';
7
+ import { printHelp, printVersion } from '../help/index.js';
8
+ import { commandNames, dispatch, findCommand } from '../commands/registry.js';
9
+ import { BIN } from '../config/settings.js';
10
+ import { shellBanner } from '../theme/index.js';
11
+ import { cyan, dim, faint, red, usePromptHandlers } from '../ui/index.js';
12
+ const HISTORY_LIMIT = 500;
13
+ const CONFIG_ACTIONS = ['show', 'path', 'set', 'unset', 'clear'];
14
+ const EXIT_WORDS = ['exit', 'quit', 'q', ':q'];
15
+ /** Split a line into arguments, keeping quoted phrases in one argument. */
16
+ export function tokenize(line) {
17
+ const tokens = [];
18
+ let current = '';
19
+ let quote = null;
20
+ let started = false;
21
+ for (const char of line) {
22
+ if (quote !== null) {
23
+ if (char === quote)
24
+ quote = null;
25
+ else
26
+ current += char;
27
+ continue;
28
+ }
29
+ if (char === '"' || char === "'") {
30
+ quote = char;
31
+ started = true;
32
+ continue;
33
+ }
34
+ if (char === ' ' || char === '\t') {
35
+ if (started || current !== '') {
36
+ tokens.push(current);
37
+ current = '';
38
+ started = false;
39
+ }
40
+ continue;
41
+ }
42
+ current += char;
43
+ started = true;
44
+ }
45
+ if (started || current !== '')
46
+ tokens.push(current);
47
+ return tokens;
48
+ }
49
+ function historyFile() {
50
+ return path.join(path.dirname(configFilePath()), 'history');
51
+ }
52
+ /** Previous lines, oldest first; the history file is a convenience only. */
53
+ function readHistory() {
54
+ try {
55
+ return fs
56
+ .readFileSync(historyFile(), 'utf8')
57
+ .split(/\r?\n/)
58
+ .filter((line) => line.trim() !== '')
59
+ .slice(-HISTORY_LIMIT);
60
+ }
61
+ catch {
62
+ return [];
63
+ }
64
+ }
65
+ function writeHistory(entries) {
66
+ const oldestFirst = [...entries].reverse().slice(-HISTORY_LIMIT);
67
+ if (oldestFirst.length === 0)
68
+ return;
69
+ try {
70
+ fs.mkdirSync(path.dirname(historyFile()), { recursive: true });
71
+ fs.writeFileSync(historyFile(), `${oldestFirst.join('\n')}\n`, 'utf8');
72
+ }
73
+ catch {
74
+ // Losing the history file must never break the shell.
75
+ }
76
+ }
77
+ /** `~/repos` instead of the full path, shortened when it gets long. */
78
+ function shortPath(cwd) {
79
+ const normal = cwd.replace(/\\/g, '/');
80
+ const home = os.homedir().replace(/\\/g, '/');
81
+ let shown = normal;
82
+ if (normal === home)
83
+ shown = '~';
84
+ else if (normal.toLowerCase().startsWith(`${home.toLowerCase()}/`)) {
85
+ shown = `~${normal.slice(home.length)}`;
86
+ }
87
+ if (shown.length > 34)
88
+ shown = `…/${shown.split('/').slice(-2).join('/')}`;
89
+ return shown;
90
+ }
91
+ function promptText() {
92
+ let user = 'guest';
93
+ try {
94
+ user = loadConfig().username ?? 'guest';
95
+ }
96
+ catch {
97
+ // A broken config file is reported by the command that needs it, not here.
98
+ }
99
+ return `${cyan(`${user}@${BIN}`)}${dim(`:${shortPath(process.cwd())}`)} ${faint('$')} `;
100
+ }
101
+ /** Commands and, after one is typed, its options. */
102
+ function complete(line) {
103
+ const tokens = line.split(/\s+/);
104
+ const current = tokens[tokens.length - 1] ?? '';
105
+ const first = tokens[0] ?? '';
106
+ let pool;
107
+ if (tokens.length <= 1) {
108
+ pool = [...commandNames(), 'clear', 'exit', 'help'];
109
+ }
110
+ else if (first === 'config' && tokens.length === 2) {
111
+ pool = CONFIG_ACTIONS;
112
+ }
113
+ else if (current.startsWith('-')) {
114
+ pool = [...(findCommand(first)?.flags ?? [])];
115
+ }
116
+ else {
117
+ pool = [];
118
+ }
119
+ const hits = [...new Set(pool)].filter((candidate) => candidate.startsWith(current)).sort();
120
+ if (hits.length === 0)
121
+ return [[], current];
122
+ // A single match is completed with a trailing space, ready for its arguments.
123
+ return [hits.length === 1 ? [`${hits[0]} `] : hits, current];
124
+ }
125
+ function printHeader(terminal) {
126
+ let config;
127
+ try {
128
+ config = loadConfig();
129
+ }
130
+ catch {
131
+ config = undefined;
132
+ }
133
+ console.log(shellBanner(config));
134
+ console.log('');
135
+ if (terminal)
136
+ console.log(` ${faint('↑↓ history tab complete clear to reset')}`);
137
+ }
138
+ /** Wipe the screen and the scrollback, so the shell opens on a clean page. */
139
+ function clearScreen() {
140
+ process.stdout.write('\u001b[2J\u001b[3J\u001b[H');
141
+ }
142
+ /**
143
+ * Interactive shell: the same commands as the one-shot CLI, with history, tab
144
+ * completion and a prompt. Runs until `exit`, Ctrl+C on an empty line or EOF.
145
+ */
146
+ export async function startShell() {
147
+ const terminal = Boolean(process.stdin.isTTY);
148
+ const rl = readline.createInterface({
149
+ input: process.stdin,
150
+ output: process.stdout,
151
+ terminal,
152
+ history: readHistory(),
153
+ historySize: HISTORY_LIMIT,
154
+ removeHistoryDuplicates: true,
155
+ completer: complete,
156
+ });
157
+ let closed = false;
158
+ let draining = false;
159
+ const queue = [];
160
+ /** Set while a running command is waiting for an answer. */
161
+ let pending = null;
162
+ const finishPending = (answer) => {
163
+ const current = pending;
164
+ pending = null;
165
+ if (current === null)
166
+ return;
167
+ current.cleanup();
168
+ current.resolve(answer);
169
+ };
170
+ const askLine = (question) => new Promise((resolve) => {
171
+ process.stdout.write(question);
172
+ pending = { resolve, cleanup: () => { } };
173
+ });
174
+ const askSecretLine = (question) => new Promise((resolve) => {
175
+ process.stdout.write(question);
176
+ const internal = rl;
177
+ const original = internal._writeToOutput;
178
+ internal._writeToOutput = () => { };
179
+ pending = {
180
+ resolve,
181
+ cleanup: () => {
182
+ internal._writeToOutput = original;
183
+ process.stdout.write('\n');
184
+ },
185
+ };
186
+ });
187
+ const prompt = () => {
188
+ rl.setPrompt(promptText());
189
+ rl.prompt();
190
+ };
191
+ const runBuiltin = (word) => {
192
+ switch (word) {
193
+ case 'help':
194
+ printHelp();
195
+ return true;
196
+ case 'clear':
197
+ if (terminal) {
198
+ clearScreen();
199
+ printHeader(terminal);
200
+ }
201
+ else {
202
+ process.stdout.write('\n');
203
+ }
204
+ return true;
205
+ case 'version':
206
+ printVersion();
207
+ return true;
208
+ default:
209
+ return false;
210
+ }
211
+ };
212
+ /** Returns true when the shell should stop. */
213
+ const handleLine = async (raw) => {
214
+ const input = raw.trim();
215
+ if (input === '') {
216
+ prompt();
217
+ return false;
218
+ }
219
+ const [word, ...args] = tokenize(input);
220
+ if (word === undefined) {
221
+ prompt();
222
+ return false;
223
+ }
224
+ if (EXIT_WORDS.includes(word)) {
225
+ rl.close();
226
+ return true;
227
+ }
228
+ if (runBuiltin(word)) {
229
+ prompt();
230
+ return false;
231
+ }
232
+ // Commands keep printing on their own; only their questions come back here.
233
+ if (terminal)
234
+ usePromptHandlers({ ask: askLine, askSecret: askSecretLine });
235
+ try {
236
+ await dispatch([word, ...args]);
237
+ }
238
+ catch (error) {
239
+ console.log(`${red('✗')} ${errorMessage(error)}`);
240
+ }
241
+ finally {
242
+ usePromptHandlers(null);
243
+ if (!closed)
244
+ prompt();
245
+ }
246
+ return false;
247
+ };
248
+ const drain = async () => {
249
+ if (draining)
250
+ return;
251
+ draining = true;
252
+ try {
253
+ while (!closed && queue.length > 0) {
254
+ const line = queue.shift();
255
+ if (line === undefined)
256
+ break;
257
+ if (await handleLine(line))
258
+ break;
259
+ }
260
+ }
261
+ finally {
262
+ draining = false;
263
+ }
264
+ };
265
+ /** Answers typed at a command's prompt are not worth keeping, and a password
266
+ * must never reach the history file. */
267
+ const dropFromHistory = (answer) => {
268
+ const history = rl.history;
269
+ if (history !== undefined && history[0] === answer)
270
+ history.shift();
271
+ };
272
+ rl.on('line', (line) => {
273
+ if (pending !== null) {
274
+ finishPending(line);
275
+ dropFromHistory(line);
276
+ return;
277
+ }
278
+ queue.push(line);
279
+ void drain();
280
+ });
281
+ rl.on('SIGINT', () => {
282
+ if (pending !== null) {
283
+ // Cancel the question; the command reports the empty answer itself.
284
+ finishPending('');
285
+ return;
286
+ }
287
+ if (draining)
288
+ return;
289
+ if (rl.line.trim() !== '') {
290
+ rl.write(null, { ctrl: true, name: 'u' });
291
+ process.stdout.write('\n');
292
+ prompt();
293
+ return;
294
+ }
295
+ process.stdout.write('\n');
296
+ rl.close();
297
+ });
298
+ rl.on('close', () => {
299
+ closed = true;
300
+ // `history` exists at runtime but is missing from @types/node, newest first.
301
+ writeHistory(rl.history);
302
+ if (terminal)
303
+ process.stdout.write('\n');
304
+ });
305
+ // Clear whatever was on screen before the shell took over.
306
+ if (terminal)
307
+ clearScreen();
308
+ printHeader(terminal);
309
+ prompt();
310
+ await new Promise((resolve) => rl.once('close', resolve));
311
+ }
312
+ //# sourceMappingURL=repl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repl.js","sourceRoot":"","sources":["../../src/cli/repl.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,305 @@
1
+ import { parseArgs } from 'node:util';
2
+ import { ApiClient, ApiError } from '../api/index.js';
3
+ import { ENV, loadConfig, normalizeUrl, readStoredConfig, resolveUrl, writeStoredConfig, } from '../config/index.js';
4
+ import { BIN } from '../config/settings.js';
5
+ import { ask, askSecret, bold, cyan, dim, fail, faint, formatDate, info, ok, printJson, warn } from '../ui/index.js';
6
+ const LOGIN_OPTIONS = {
7
+ url: { type: 'string' },
8
+ username: { type: 'string', short: 'u' },
9
+ password: { type: 'string', short: 'p' },
10
+ 'save-password': { type: 'boolean' },
11
+ 'forget-password': { type: 'boolean' },
12
+ force: { type: 'boolean' },
13
+ json: { type: 'boolean' },
14
+ help: { type: 'boolean', short: 'h' },
15
+ };
16
+ function text(value) {
17
+ return typeof value === 'string' && value !== '' ? value : undefined;
18
+ }
19
+ function trimmed(value) {
20
+ const valueText = text(value)?.trim();
21
+ return valueText === '' ? undefined : valueText;
22
+ }
23
+ function printLoginHelp() {
24
+ console.log(`Usage: ${BIN} login [username] [options]
25
+
26
+ Sign in and store the API session token for later commands. A stored session
27
+ that is still valid is reused, so your username and password are not asked for
28
+ again; pass --force to sign in as another account.
29
+
30
+ Options:
31
+ --url <url> Server URL (default: stored, then http://{HOST_NAME}:{PORT})
32
+ -u, --username Account name (also ${ENV.username})
33
+ -p, --password Password (also ${ENV.password})
34
+ --save-password Also store the password for git push/pull/clone
35
+ --forget-password Remove any password saved by an earlier login
36
+ --force Sign in again even when a session is stored
37
+ --json Print the result as JSON
38
+ -h, --help Show this help
39
+
40
+ Examples:
41
+ ${BIN} login
42
+ ${BIN} login alice --url http://{HOST_NAME}:{PORT} --save-password`);
43
+ }
44
+ function printRegisterHelp() {
45
+ console.log(`Usage: ${BIN} register [username] [options]
46
+
47
+ Create an account (when the server allows registration) and sign in.
48
+
49
+ Options:
50
+ --url <url> Server URL
51
+ -u, --username Account name (also ${ENV.username})
52
+ -p, --password Password (also ${ENV.password})
53
+ --save-password Also store the password for git push/pull/clone
54
+ --forget-password Remove any password saved by an earlier login
55
+ --json Print the result as JSON
56
+ -h, --help Show this help`);
57
+ }
58
+ /** Save the session fields, optionally the git password, and keep the URL. */
59
+ function saveSession(url, username, token, expiresAt, password, forgetPassword) {
60
+ const stored = readStoredConfig();
61
+ const next = {
62
+ ...stored,
63
+ url,
64
+ username,
65
+ token,
66
+ expiresAt,
67
+ };
68
+ if (password !== undefined)
69
+ next.password = password;
70
+ else if (forgetPassword)
71
+ delete next.password;
72
+ else if (stored.password && stored.username === username)
73
+ next.password = stored.password;
74
+ else
75
+ delete next.password;
76
+ writeStoredConfig(next);
77
+ }
78
+ /** The server's message of the day, when it publishes one. */
79
+ function showMotd(motd) {
80
+ const message = motd?.trim();
81
+ if (!message)
82
+ return;
83
+ console.log('');
84
+ console.log(`${faint('#')} ${dim('message from the server')}`);
85
+ for (const line of message.split(/\r?\n/))
86
+ console.log(` ${line}`);
87
+ console.log('');
88
+ }
89
+ /**
90
+ * Reuse the stored session when it is still valid. Returns true when the caller
91
+ * should stop: the user is already signed in.
92
+ */
93
+ async function reuseSession(flagUrl, stored, json) {
94
+ if (!stored.token)
95
+ return false;
96
+ const url = resolveUrl(flagUrl);
97
+ // A token belongs to the server it was issued by.
98
+ if (stored.url !== undefined && normalizeUrl(stored.url) !== url)
99
+ return false;
100
+ const expiresAt = stored.expiresAt;
101
+ if (expiresAt !== undefined && new Date(expiresAt).getTime() <= Date.now())
102
+ return false;
103
+ let user;
104
+ try {
105
+ user = await new ApiClient(url, stored.token).me();
106
+ }
107
+ catch (error) {
108
+ if (error instanceof ApiError && error.status === 401) {
109
+ info('The stored session is no longer valid; signing in again.');
110
+ return false;
111
+ }
112
+ throw error;
113
+ }
114
+ if (json) {
115
+ printJson({ url, user, expiresAt, motd: user.motd, alreadySignedIn: true });
116
+ return true;
117
+ }
118
+ ok(`Already signed in as ${bold(user.username)}${user.admin ? bold(' (admin)') : ''}`);
119
+ info(`Server: ${url}`);
120
+ if (expiresAt)
121
+ info(`Session expires: ${formatDate(expiresAt)}`);
122
+ showMotd(user.motd);
123
+ info(`Use --force to sign in again, or ${cyan(`${BIN} logout`)} first.`);
124
+ return true;
125
+ }
126
+ export async function loginCommand(argv) {
127
+ const { values, positionals } = parseArgs({
128
+ args: argv,
129
+ allowPositionals: true,
130
+ options: LOGIN_OPTIONS,
131
+ });
132
+ if (values.help)
133
+ return printLoginHelp();
134
+ const stored = readStoredConfig();
135
+ const url = resolveUrl(text(values.url));
136
+ const flagUser = trimmed(values.username) ?? trimmed(positionals[0]);
137
+ const envUser = trimmed(process.env[ENV.username]);
138
+ const flagPassword = text(values.password) ?? process.env[ENV.password];
139
+ // 1. A valid stored session wins: do not ask for the username again.
140
+ if (!values.force && flagUser === undefined && envUser === undefined && flagPassword === undefined) {
141
+ if (await reuseSession(text(values.url), stored, Boolean(values.json)))
142
+ return;
143
+ }
144
+ const username = flagUser ?? envUser ?? stored.username;
145
+ let user = username;
146
+ if (!user) {
147
+ if (!process.stdin.isTTY)
148
+ fail('Username is required. Pass --username or run interactively.');
149
+ user = await ask('Username: ');
150
+ }
151
+ let password = flagPassword;
152
+ if (!password) {
153
+ if (!process.stdin.isTTY)
154
+ fail('Password is required. Pass --password or set the password env var.');
155
+ password = await askSecret('Password: ');
156
+ }
157
+ if (!password)
158
+ fail('Password cannot be empty.');
159
+ const api = new ApiClient(url);
160
+ const result = await api.login(user, password);
161
+ saveSession(url, result.user.username, result.token, result.expiresAt, values['save-password'] ? password : undefined, Boolean(values['forget-password']));
162
+ if (values.json) {
163
+ printJson({
164
+ url,
165
+ user: result.user,
166
+ expiresAt: result.expiresAt,
167
+ motd: result.motd,
168
+ });
169
+ return;
170
+ }
171
+ ok(`Signed in as ${bold(result.user.username)}${result.user.admin ? bold(' (admin)') : ''}`);
172
+ info(`Server: ${url}`);
173
+ info(`Session expires: ${formatDate(result.expiresAt)}`);
174
+ if (values['save-password'])
175
+ info('Password saved for git commands.');
176
+ showMotd(result.motd);
177
+ }
178
+ export async function registerCommand(argv) {
179
+ const { values, positionals } = parseArgs({
180
+ args: argv,
181
+ allowPositionals: true,
182
+ options: LOGIN_OPTIONS,
183
+ });
184
+ if (values.help)
185
+ return printRegisterHelp();
186
+ const stored = readStoredConfig();
187
+ const url = resolveUrl(text(values.url));
188
+ const username = trimmed(values.username) ??
189
+ trimmed(positionals[0]) ??
190
+ trimmed(process.env[ENV.username]) ??
191
+ stored.username;
192
+ let user = username;
193
+ if (!user) {
194
+ if (!process.stdin.isTTY)
195
+ fail('Username is required. Pass --username or run interactively.');
196
+ user = await ask('Username: ');
197
+ }
198
+ let password = text(values.password) ?? process.env[ENV.password];
199
+ if (!password) {
200
+ if (!process.stdin.isTTY)
201
+ fail('Password is required. Pass --password or set the password env var.');
202
+ password = await askSecret('Password: ');
203
+ const repeated = await askSecret('Repeat password: ');
204
+ if (password !== repeated)
205
+ fail('Passwords do not match.');
206
+ }
207
+ if (!password)
208
+ fail('Password cannot be empty.');
209
+ const api = new ApiClient(url);
210
+ const result = await api.register(user, password);
211
+ saveSession(url, result.user.username, result.token, result.expiresAt, values['save-password'] ? password : undefined, Boolean(values['forget-password']));
212
+ if (values.json) {
213
+ printJson({
214
+ url,
215
+ user: result.user,
216
+ expiresAt: result.expiresAt,
217
+ motd: result.motd,
218
+ });
219
+ return;
220
+ }
221
+ ok(`Account created and signed in as ${bold(result.user.username)}`);
222
+ info(`Server: ${url}`);
223
+ info(`Session expires: ${formatDate(result.expiresAt)}`);
224
+ if (values['save-password'])
225
+ info('Password saved for git commands.');
226
+ showMotd(result.motd);
227
+ }
228
+ export async function logoutCommand(argv) {
229
+ const { values } = parseArgs({
230
+ args: argv,
231
+ allowPositionals: true,
232
+ options: {
233
+ url: { type: 'string' },
234
+ json: { type: 'boolean' },
235
+ help: { type: 'boolean', short: 'h' },
236
+ },
237
+ });
238
+ if (values.help) {
239
+ console.log(`Usage: ${BIN} logout [--url <url>] [--json]`);
240
+ return;
241
+ }
242
+ const config = loadConfig(text(values.url));
243
+ let revoked = false;
244
+ if (config.token) {
245
+ try {
246
+ const result = await new ApiClient(config.url, config.token).logout();
247
+ revoked = result.loggedOut;
248
+ }
249
+ catch (error) {
250
+ if (error instanceof ApiError && error.status === 401) {
251
+ // The session was already gone; clearing the local file is still right.
252
+ }
253
+ else {
254
+ warn(`Could not revoke the server session: ${error.message}`);
255
+ }
256
+ }
257
+ }
258
+ const stored = readStoredConfig();
259
+ writeStoredConfig({
260
+ url: stored.url ?? config.url,
261
+ username: stored.username ?? config.username,
262
+ });
263
+ if (values.json) {
264
+ printJson({ loggedOut: revoked, url: config.url });
265
+ return;
266
+ }
267
+ if (config.token)
268
+ ok('Signed out. Local session and saved password were removed.');
269
+ else
270
+ info('Already signed out. Local credentials were cleared.');
271
+ }
272
+ export async function whoamiCommand(argv) {
273
+ const { values } = parseArgs({
274
+ args: argv,
275
+ allowPositionals: true,
276
+ options: {
277
+ url: { type: 'string' },
278
+ json: { type: 'boolean' },
279
+ help: { type: 'boolean', short: 'h' },
280
+ },
281
+ });
282
+ if (values.help) {
283
+ console.log(`Usage: ${BIN} whoami [--url <url>] [--json]`);
284
+ return;
285
+ }
286
+ const config = loadConfig(text(values.url));
287
+ if (!config.token) {
288
+ fail(`You are not signed in. Run \`${BIN} login\` first.`);
289
+ }
290
+ const user = await new ApiClient(config.url, config.token).me();
291
+ if (values.json) {
292
+ printJson({
293
+ url: config.url,
294
+ user,
295
+ expiresAt: config.expiresAt,
296
+ });
297
+ return;
298
+ }
299
+ ok(`Signed in as ${bold(user.username)}${user.admin ? bold(' (admin)') : ''}`);
300
+ info(`Server: ${config.url}`);
301
+ if (config.expiresAt)
302
+ info(`Session expires: ${formatDate(config.expiresAt)}`);
303
+ showMotd(user.motd);
304
+ }
305
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"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"}