UNPKG

@vigilbase/cli

Version:

Vigilbase CLI — security scanners, agent tools, and Vigilbase One from the terminal.

106 lines (105 loc) • 8.59 kB
/** * Stable error codes for `vigilbase cloudflare-checkup` (spec §F8). * * Every code matches `formatError`'s code pattern. Messages and hints are * authored here; cf stderr and Vigilbase server text are never echoed. Hints * point at the one command ("run the same command again", `--yes`, * `--account-id`), not at the advanced subcommands. The browser * troubleshooting accordion mirrors the code set. */ import { CF_TOKEN_ENV } from './cf/child-env.js'; import { PRODUCTION_ORIGIN } from './contract.js'; export const LOCAL_ERROR_CODES = [ // Environment and cf 'NODE_UNSUPPORTED', 'CF_NOT_FOUND', 'CF_WRONG_BINARY', 'CF_UNSUPPORTED_VERSION', 'CF_ALLOWLIST_MISMATCH', 'CF_INSTALL_FAILED', 'CF_AUTH_REQUIRED', 'CF_PERMISSION_DENIED', 'CF_RATE_LIMITED', 'CF_ERROR', // Account 'ACCOUNT_SELECTION_REQUIRED', 'ACCOUNT_NOT_VISIBLE', 'ACCOUNT_TOO_LARGE', 'ACCOUNT_MISMATCH', // Files and snapshots 'OUTPUT_EXISTS', 'SNAPSHOT_INVALID', 'SNAPSHOT_TOO_LARGE', 'SNAPSHOT_STALE', 'SNAPSHOT_SECRET_LIKE_VALUE', // Email verification 'EMAIL_INVALID', 'EMAIL_CODE_INVALID', 'VERIFICATION_INVALID', 'VERIFICATION_EXPIRED', // Session 'SESSION_INVALID', 'SESSION_EXPIRED', 'SESSION_USED', 'SESSION_BUSY', 'SESSION_CLOSED', // Submission 'SUBMIT_ORIGIN_UNTRUSTED', 'CONFIRMATION_REQUIRED', 'CLI_UPGRADE_REQUIRED', 'LOCAL_MODE_DISABLED', 'VIGILBASE_RATE_LIMITED', 'VIGILBASE_CHALLENGED', 'SUBMIT_FAILED', ]; const INSTALL_CF = '`npm install --global cf@1.0.0-beta.13`'; /** LOCAL_MODE_DISABLED: the browser checkup on the origin the CLI talks to (vigilbase.com, or a loopback dev server). */ export function browserCheckupHint(origin) { return `Run the Cloudflare Checkup in your browser instead: ${origin}/tools/cloudflare-checkup`; } /** One fix per code; shown after the error and in `--json` as `hint`. */ export const LOCAL_ERROR_HINTS = { NODE_UNSUPPORTED: 'Install Node.js 22.18 or newer from https://nodejs.org (cf runs under the same Node), then run the same command again.', CF_NOT_FOUND: `Run the same command again in a terminal and let it install cf (add --yes when no terminal is available), or install it yourself with ${INSTALL_CF}.`, CF_WRONG_BINARY: `Another program named cf (for example the Cloud Foundry CLI, or a pnpm or Volta shim) was found. Run the same command again without --cf-bin and let it install cf, or pass --cf-bin "$(npm root -g)/cf".`, CF_UNSUPPORTED_VERSION: `Run the same command again without --cf-bin and let it install the tested cf 1.0.0-beta.13, or install it yourself with ${INSTALL_CF}.`, // Without --cf-bin the one command offers the managed install itself; the user's own cf is left alone. CF_ALLOWLIST_MISMATCH: 'This cf release renamed commands the checkup needs. Run the same command again without --cf-bin and let it install the tested cf 1.0.0-beta.13 for Vigilbase; your own cf is left alone.', CF_INSTALL_FAILED: `Install cf yourself with ${INSTALL_CF}, then run the same command again.`, CF_AUTH_REQUIRED: `Run the same command again in a terminal to sign in to Cloudflare with a read-only login, or set ${CF_TOKEN_ENV} in this shell first.`, CF_PERMISSION_DENIED: 'Your Cloudflare login cannot read this account\'s zones. Check its permissions, then run the same command again.', CF_RATE_LIMITED: 'Cloudflare paused your API access. Wait 5 minutes, then run the same command again; add --max-requests-per-5min 600 if it repeats.', CF_ERROR: 'Run the same command again in a few minutes. If it persists, contact help@vigilbase.com.', ACCOUNT_SELECTION_REQUIRED: 'Run the same command again in a terminal to choose the account, or add --account-id <ACCOUNT_ID> with one of the IDs listed.', ACCOUNT_NOT_VISIBLE: 'Check that your Cloudflare user can read the account and its zones, then run the same command again.', ACCOUNT_TOO_LARGE: 'Local collection supports up to 100 zones. Use the browser token mode on vigilbase.com instead.', ACCOUNT_MISMATCH: 'This checkup is for a different Cloudflare account. Run the same command again without --account-id to start a new checkup.', OUTPUT_EXISTS: 'Choose another --out path, or pass --overwrite to replace the file.', SNAPSHOT_INVALID: 'The file is not a valid snapshot. Run the same command again to collect a fresh one.', SNAPSHOT_TOO_LARGE: 'The snapshot is over the upload limit. Use the browser token mode on vigilbase.com instead.', SNAPSHOT_STALE: 'Snapshots are accepted for 24 hours. Run the same command again to collect a fresh one.', SNAPSHOT_SECRET_LIKE_VALUE: 'The snapshot contains a value that looks like a credential. Remove it from the Cloudflare rule description or name, then run the same command again.', EMAIL_INVALID: 'Use your work email address (personal and disposable addresses are not accepted), then run the same command again.', EMAIL_CODE_INVALID: 'Run the same command again to get a new code, and enter the 6 digits from the newest email.', VERIFICATION_INVALID: 'Run the same command again to get a new code by email.', VERIFICATION_EXPIRED: 'Run the same command again to get a new code by email, and enter it before the time shown.', SESSION_INVALID: 'Run the same command again to verify your email and start a new checkup.', SESSION_EXPIRED: 'Run the same command again to verify your email and start a new checkup.', SESSION_USED: 'This checkup already has results. Run the same command again to start a new checkup.', SESSION_BUSY: 'A snapshot for this checkup is still being processed. Wait for the results email, or run the same command again to start a new checkup.', SESSION_CLOSED: 'This checkup was cancelled or has expired. Run the same command again to start a new one.', SUBMIT_ORIGIN_UNTRUSTED: 'Upload only to https://vigilbase.com (or a loopback origin for local testing).', CONFIRMATION_REQUIRED: 'Run the command in a terminal to confirm the upload, or add --yes.', CLI_UPGRADE_REQUIRED: 'Run `npx @vigilbase/cli@latest cloudflare-checkup`, or upgrade with `npm install --global @vigilbase/cli@latest`.', LOCAL_MODE_DISABLED: browserCheckupHint(PRODUCTION_ORIGIN), VIGILBASE_RATE_LIMITED: 'Too many requests to vigilbase.com. Wait as long as the error says (a few minutes if it says nothing), then run the same command again.', VIGILBASE_CHALLENGED: 'vigilbase.com asked for a browser challenge. Try another network, or contact help@vigilbase.com.', SUBMIT_FAILED: 'Run the same command again in a few minutes. If it persists, contact help@vigilbase.com.', }; /** * CF_AUTH_REQUIRED in env mode (`--cf-auth env`, or `auto` with the variable * set): the browser sign-in is never offered while the token is used, so the * hint names both ways out. */ export const ENV_TOKEN_AUTH_HINT = `Set ${CF_TOKEN_ENV} in this shell to a valid read-only Cloudflare API token (read -rs ${CF_TOKEN_ENV} && export ${CF_TOKEN_ENV}) and run the same command again, or unset it (or use --cf-auth profile) to sign in with your browser instead.`; /** SNAPSHOT_INVALID for an `inspect` or `submit` path with no file: nothing to collect again, so how to make one. */ export const SNAPSHOT_MISSING_HINT = 'Check the file path. To collect a snapshot into a file, run `npx @vigilbase/cli cloudflare-checkup collect --out <file>`.'; /** CF_PERMISSION_DENIED in env mode: the token lacks a read permission; the browser sign-in is the other way out. */ export const ENV_TOKEN_PERMISSION_HINT = `The API token in ${CF_TOKEN_ENV} cannot read everything the checkup needs. Add the read permissions to it, or unset it (or use --cf-auth profile) to sign in with your browser instead, then run the same command again.`; export class LocalCheckupError extends Error { code; hint; /** HTTP status of the Cloudflare or Vigilbase response, when one caused the error. */ status; retryAfterSec; constructor(code, message, options = {}) { super(message); this.name = 'LocalCheckupError'; this.code = code; this.hint = options.hint ?? LOCAL_ERROR_HINTS[code]; if (options.status !== undefined) this.status = options.status; if (options.retryAfterSec !== undefined) this.retryAfterSec = options.retryAfterSec; } /** Mapped to exit code 2 by `runCli`. */ get isRateLimited() { return this.code === 'CF_RATE_LIMITED' || this.code === 'VIGILBASE_RATE_LIMITED'; } } export function isLocalCheckupError(error) { return error instanceof LocalCheckupError; }