SPB Git

spb/spbgit Public MIT

SPB Git — the platform hosting itself

JavaScript 73.9% CSS 11.7% Nunjucks 11.6% Shell 2.7%
2.4 KB · 59 lines javascript
Raw Blame History
1/**2 * ─────────────────────────────────────────────3 *  SPB Git — Personal Git Platform4 * ─────────────────────────────────────────────5 *  Author  : Simon-Pierre Boucher6 *  Contact : contact@spboucher.ai7 *  File    : cli/commands/token.mjs8 *  Purpose : `spbgit token new|list|revoke` — PAT management9 *  License : MIT © Simon-Pierre Boucher10 * ─────────────────────────────────────────────11 */1213import pc from 'picocolors';14import { requireCliConfig } from '../lib/config.mjs';15import { api } from '../lib/api.mjs';16import { printTable } from '../lib/ui.mjs';1718export function registerToken(program) {19  const token = program.command('token').description('manage personal access tokens');2021  token22    .command('new')23    .description('mint a new PAT (shown exactly once)')24    .option('--label <label>', 'token label', 'cli')25    .action(async (opts) => {26      const config = requireCliConfig();27      const result = await api(config, 'POST', '/api/v1/tokens', { label: opts.label });28      console.log(`${pc.green('✓')} New token (label: ${result.label}) — copy it now, it will never be shown again:\n`);29      console.log(`  ${pc.bold(result.token)}\n`);30      console.log(pc.dim('Store it with `spbgit init` on the machine that will use it.'));31    });3233  token34    .command('list')35    .description('list tokens (hashes never leave the server)')36    .option('--json', 'machine-readable output')37    .action(async (opts) => {38      const config = requireCliConfig();39      const { tokens } = await api(config, 'GET', '/api/v1/tokens');40      if (opts.json) {41        console.log(JSON.stringify(tokens, null, 2));42        return;43      }44      printTable([45        [pc.bold('ID'), pc.bold('LABEL'), pc.bold('CREATED'), pc.bold('LAST USED')],46        ...tokens.map((t) => [t.id, t.label, t.created?.slice(0, 10) ?? '', t.lastUsed?.slice(0, 16)?.replace('T', ' ') ?? pc.dim('never')]),47      ]);48    });4950  token51    .command('revoke <id>')52    .description('revoke a token by id')53    .action(async (id) => {54      const config = requireCliConfig();55      await api(config, 'DELETE', `/api/v1/tokens/${encodeURIComponent(id)}`);56      console.log(`${pc.green('✓')} Token ${id} revoked.`);57    });58}59