@lifestreamdynamics/vault-cli 1.1.0 → 1.3.0

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 (56) hide show
  1. package/README.md +140 -30
  2. package/dist/client.d.ts +4 -0
  3. package/dist/client.js +12 -11
  4. package/dist/commands/admin.js +5 -5
  5. package/dist/commands/ai.d.ts +2 -0
  6. package/dist/commands/ai.js +124 -0
  7. package/dist/commands/analytics.d.ts +2 -0
  8. package/dist/commands/analytics.js +84 -0
  9. package/dist/commands/auth.js +10 -105
  10. package/dist/commands/booking.d.ts +2 -0
  11. package/dist/commands/booking.js +739 -0
  12. package/dist/commands/calendar.js +778 -6
  13. package/dist/commands/completion.d.ts +5 -0
  14. package/dist/commands/completion.js +60 -0
  15. package/dist/commands/config.js +17 -16
  16. package/dist/commands/connectors.js +12 -1
  17. package/dist/commands/custom-domains.d.ts +2 -0
  18. package/dist/commands/custom-domains.js +154 -0
  19. package/dist/commands/docs.js +152 -5
  20. package/dist/commands/hooks.js +6 -1
  21. package/dist/commands/links.js +9 -2
  22. package/dist/commands/mfa.js +1 -70
  23. package/dist/commands/plugins.d.ts +2 -0
  24. package/dist/commands/plugins.js +172 -0
  25. package/dist/commands/publish-vault.d.ts +2 -0
  26. package/dist/commands/publish-vault.js +117 -0
  27. package/dist/commands/publish.js +63 -2
  28. package/dist/commands/saml.d.ts +2 -0
  29. package/dist/commands/saml.js +220 -0
  30. package/dist/commands/scim.d.ts +2 -0
  31. package/dist/commands/scim.js +238 -0
  32. package/dist/commands/shares.js +25 -3
  33. package/dist/commands/subscription.js +9 -2
  34. package/dist/commands/sync.js +3 -0
  35. package/dist/commands/teams.js +233 -4
  36. package/dist/commands/user.js +444 -0
  37. package/dist/commands/vaults.js +240 -8
  38. package/dist/commands/webhooks.js +6 -1
  39. package/dist/config.d.ts +2 -0
  40. package/dist/config.js +7 -3
  41. package/dist/index.js +28 -1
  42. package/dist/lib/credential-manager.js +32 -7
  43. package/dist/lib/migration.js +2 -2
  44. package/dist/lib/profiles.js +4 -4
  45. package/dist/sync/config.js +2 -2
  46. package/dist/sync/daemon-worker.js +13 -6
  47. package/dist/sync/daemon.js +2 -1
  48. package/dist/sync/remote-poller.js +7 -3
  49. package/dist/sync/state.js +2 -2
  50. package/dist/utils/confirm.d.ts +11 -0
  51. package/dist/utils/confirm.js +23 -0
  52. package/dist/utils/format.js +1 -1
  53. package/dist/utils/output.js +4 -1
  54. package/dist/utils/prompt.d.ts +29 -0
  55. package/dist/utils/prompt.js +146 -0
  56. package/package.json +2 -2
@@ -4,6 +4,7 @@ import { LifestreamVaultClient } from '@lifestreamdynamics/vault-sdk';
4
4
  import { loadConfigAsync, getCredentialManager } from '../config.js';
5
5
  import { getClientAsync } from '../client.js';
6
6
  import { migrateCredentials, hasPlaintextCredentials, checkAndPromptMigration } from '../lib/migration.js';
7
+ import { promptPassword, promptMfaCode } from '../utils/prompt.js';
7
8
  export function registerAuthCommands(program) {
8
9
  const auth = program.command('auth').description('Authentication and credential management');
9
10
  auth.command('login')
@@ -38,6 +39,7 @@ EXAMPLES
38
39
  const password = opts.password ?? await promptPassword();
39
40
  if (!password) {
40
41
  console.error(chalk.red('Password is required for email login.'));
42
+ process.exitCode = 1;
41
43
  return;
42
44
  }
43
45
  const config = await loadConfigAsync();
@@ -64,7 +66,7 @@ EXAMPLES
64
66
  refreshToken: refreshToken ?? undefined,
65
67
  });
66
68
  spinner.succeed(`Logged in as ${chalk.cyan(tokens.user.email)}`);
67
- console.log(` Name: ${tokens.user.name || chalk.dim('not set')}`);
69
+ console.log(` Name: ${tokens.user.displayName || chalk.dim('not set')}`);
68
70
  console.log(` Role: ${tokens.user.role}`);
69
71
  if (!refreshToken) {
70
72
  console.log(chalk.yellow(' Note: No refresh token received. Session will expire.'));
@@ -73,6 +75,7 @@ EXAMPLES
73
75
  catch (err) {
74
76
  spinner.fail('Login failed');
75
77
  console.error(err instanceof Error ? err.message : String(err));
78
+ process.exitCode = 1;
76
79
  }
77
80
  return;
78
81
  }
@@ -87,6 +90,7 @@ EXAMPLES
87
90
  catch (err) {
88
91
  spinner.fail('Failed to save API key to secure storage');
89
92
  console.error(err instanceof Error ? err.message : String(err));
93
+ process.exitCode = 1;
90
94
  }
91
95
  return;
92
96
  }
@@ -102,6 +106,7 @@ EXAMPLES
102
106
  const config = await loadConfigAsync();
103
107
  if (!config.refreshToken) {
104
108
  console.error(chalk.red('No refresh token stored. Login first with --email.'));
109
+ process.exitCode = 1;
105
110
  return;
106
111
  }
107
112
  const spinner = ora('Refreshing access token...').start();
@@ -126,6 +131,7 @@ EXAMPLES
126
131
  spinner.fail('Token refresh failed');
127
132
  console.error(err instanceof Error ? err.message : String(err));
128
133
  console.log(chalk.dim('You may need to log in again: lsvault auth login --email <email>'));
134
+ process.exitCode = 1;
129
135
  }
130
136
  });
131
137
  auth.command('logout')
@@ -198,119 +204,18 @@ EXAMPLES
198
204
  const user = await client.user.me();
199
205
  spinner.stop();
200
206
  console.log(`User: ${chalk.cyan(user.email)}`);
201
- console.log(`Name: ${user.name || chalk.dim('not set')}`);
207
+ console.log(`Name: ${user.displayName || chalk.dim('not set')}`);
202
208
  console.log(`Role: ${user.role}`);
203
209
  console.log(`Plan: ${chalk.green(user.subscriptionTier)}`);
204
210
  }
205
211
  catch (err) {
206
212
  spinner.fail('Could not fetch user info');
207
- console.error(err instanceof Error ? err.message : err);
213
+ console.error(err instanceof Error ? err.message : String(err));
214
+ process.exitCode = 1;
208
215
  }
209
216
  }
210
217
  });
211
218
  }
212
- /**
213
- * Prompt for a password from stdin (non-echoing).
214
- * Returns the password or null if stdin is not a TTY.
215
- */
216
- async function promptPassword() {
217
- // In non-interactive mode, cannot prompt
218
- if (!process.stdin.isTTY) {
219
- return null;
220
- }
221
- const readline = await import('node:readline');
222
- return new Promise((resolve) => {
223
- const rl = readline.createInterface({
224
- input: process.stdin,
225
- output: process.stderr,
226
- terminal: true,
227
- });
228
- // Disable echoing
229
- process.stderr.write('Password: ');
230
- process.stdin.setRawMode?.(true);
231
- let password = '';
232
- const onData = (chunk) => {
233
- const char = chunk.toString('utf-8');
234
- if (char === '\n' || char === '\r' || char === '\u0004') {
235
- process.stderr.write('\n');
236
- process.stdin.setRawMode?.(false);
237
- process.stdin.removeListener('data', onData);
238
- rl.close();
239
- resolve(password);
240
- }
241
- else if (char === '\u0003') {
242
- // Ctrl+C
243
- process.stderr.write('\n');
244
- process.stdin.setRawMode?.(false);
245
- process.stdin.removeListener('data', onData);
246
- rl.close();
247
- resolve(null);
248
- }
249
- else if (char === '\u007F' || char === '\b') {
250
- // Backspace
251
- if (password.length > 0) {
252
- password = password.slice(0, -1);
253
- }
254
- }
255
- else {
256
- password += char;
257
- }
258
- };
259
- process.stdin.on('data', onData);
260
- process.stdin.resume();
261
- });
262
- }
263
- /**
264
- * Prompt for an MFA code from stdin (6 digits, non-echoing).
265
- * Returns the code or null if stdin is not a TTY.
266
- */
267
- async function promptMfaCode() {
268
- // In non-interactive mode, cannot prompt
269
- if (!process.stdin.isTTY) {
270
- return null;
271
- }
272
- const readline = await import('node:readline');
273
- return new Promise((resolve) => {
274
- const rl = readline.createInterface({
275
- input: process.stdin,
276
- output: process.stderr,
277
- terminal: true,
278
- });
279
- // Disable echoing
280
- process.stderr.write('MFA code: ');
281
- process.stdin.setRawMode?.(true);
282
- let code = '';
283
- const onData = (chunk) => {
284
- const char = chunk.toString('utf-8');
285
- if (char === '\n' || char === '\r' || char === '\u0004') {
286
- process.stderr.write('\n');
287
- process.stdin.setRawMode?.(false);
288
- process.stdin.removeListener('data', onData);
289
- rl.close();
290
- resolve(code);
291
- }
292
- else if (char === '\u0003') {
293
- // Ctrl+C
294
- process.stderr.write('\n');
295
- process.stdin.setRawMode?.(false);
296
- process.stdin.removeListener('data', onData);
297
- rl.close();
298
- resolve(null);
299
- }
300
- else if (char === '\u007F' || char === '\b') {
301
- // Backspace
302
- if (code.length > 0) {
303
- code = code.slice(0, -1);
304
- }
305
- }
306
- else {
307
- code += char;
308
- }
309
- };
310
- process.stdin.on('data', onData);
311
- process.stdin.resume();
312
- });
313
- }
314
219
  function formatMethod(method) {
315
220
  switch (method) {
316
221
  case 'keychain': return chalk.green('OS Keychain');
@@ -0,0 +1,2 @@
1
+ import type { Command } from 'commander';
2
+ export declare function registerBookingCommands(program: Command): void;