Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions src/cli-core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import { Command as CommanderCommand } from 'commander';
import type { Argument, CommandSpec, Specs } from './types.js';
import { printDeprecated } from './utils/messages.js';
import { exitWithError } from './utils/exit.js';

export interface ModuleLoader {
(commandPath: string[]): Promise<{
Expand Down Expand Up @@ -33,16 +34,11 @@ export function setupErrorHandlers() {
console.error('\nOperation cancelled');
process.exit(1);
}
console.error(
'\nError:',
reason instanceof Error ? reason.message : reason
);
process.exit(1);
exitWithError(reason);
Comment thread
cursor[bot] marked this conversation as resolved.
});

process.on('uncaughtException', (error) => {
console.error('\nError:', error.message);
process.exit(1);
exitWithError(error);
});
}

Expand Down Expand Up @@ -369,6 +365,11 @@ async function loadAndExecuteCommand(
positionalArgs: string[] = [],
options: Record<string, unknown> = {}
) {
// Set JSON mode globally for error handlers
if (options.json || options.format === 'json') {
globalThis.__TIGRIS_JSON_MODE = true;
}

const { module, error: loadError } = await loadModule(pathParts);

if (loadError || !module) {
Expand Down
4 changes: 4 additions & 0 deletions src/global.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,7 @@ declare module '*.yaml' {
const content: string;
export default content;
}

// Global JSON mode flag set by CLI core when --json or --format=json is used
// eslint-disable-next-line no-var
declare var __TIGRIS_JSON_MODE: boolean | undefined;
53 changes: 42 additions & 11 deletions src/lib/access-keys/assign.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ import {
printFailure,
msg,
} from '../../utils/messages.js';
import {
exitWithError,
getSuccessNextActions,
printNextActions,
} from '../../utils/exit.js';

const context = msg('access-keys', 'assign');

Expand Down Expand Up @@ -44,12 +49,12 @@ export default async function assign(options: Record<string, unknown>) {

if (!id) {
printFailure(context, 'Access key ID is required');
process.exit(1);
exitWithError('Access key ID is required', context);
}

if (admin && revokeRoles) {
printFailure(context, 'Cannot use --admin and --revoke-roles together');
process.exit(1);
exitWithError('Cannot use --admin and --revoke-roles together', context);
}

const loginMethod = await getLoginMethod();
Expand All @@ -59,15 +64,21 @@ export default async function assign(options: Record<string, unknown>) {
context,
'Bucket roles can only be managed when logged in via OAuth.\nRun "tigris login oauth" first.'
);
process.exit(1);
exitWithError(
'Bucket roles can only be managed when logged in via OAuth.\nRun "tigris login oauth" first.',
context
);
}

const authClient = getAuthClient();
const isAuthenticated = await authClient.isAuthenticated();

if (!isAuthenticated) {
printFailure(context, 'Not authenticated. Run "tigris login oauth" first.');
process.exit(1);
exitWithError(
'Not authenticated. Run "tigris login oauth" first.',
context
);
}

const accessToken = await authClient.getAccessToken();
Expand All @@ -85,7 +96,7 @@ export default async function assign(options: Record<string, unknown>) {

if (error) {
printFailure(context, error.message);
process.exit(1);
exitWithError(error, context);
}

if (format === 'json') {
Expand All @@ -107,15 +118,21 @@ export default async function assign(options: Record<string, unknown>) {
context,
'At least one bucket name is required (or use --admin or --revoke-roles)'
);
process.exit(1);
exitWithError(
'At least one bucket name is required (or use --admin or --revoke-roles)',
context
);
}

if (roles.length === 0) {
printFailure(
context,
'At least one role is required (or use --admin or --revoke-roles)'
);
process.exit(1);
exitWithError(
'At least one role is required (or use --admin or --revoke-roles)',
context
);
}

// Validate all roles
Expand All @@ -125,7 +142,10 @@ export default async function assign(options: Record<string, unknown>) {
context,
`Invalid role "${role}". Valid roles are: ${validRoles.join(', ')}`
);
process.exit(1);
exitWithError(
`Invalid role "${role}". Valid roles are: ${validRoles.join(', ')}`,
context
);
}
}

Expand All @@ -147,20 +167,31 @@ export default async function assign(options: Record<string, unknown>) {
context,
`Number of roles (${roles.length}) must be 1 or match number of buckets (${buckets.length})`
);
process.exit(1);
exitWithError(
`Number of roles (${roles.length}) must be 1 or match number of buckets (${buckets.length})`,
context
);
}
}

const { error } = await assignBucketRoles(id, assignments, { config });

if (error) {
printFailure(context, error.message);
process.exit(1);
exitWithError(error, context);
}

if (format === 'json') {
console.log(JSON.stringify({ action: 'assigned', id, assignments }));
const nextActions = getSuccessNextActions(context);
const output: Record<string, unknown> = {
action: 'assigned',
id,
assignments,
};
if (nextActions.length > 0) output.nextActions = nextActions;
console.log(JSON.stringify(output));
}

printSuccess(context);
printNextActions(context);
}
40 changes: 28 additions & 12 deletions src/lib/access-keys/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ import {
printFailure,
msg,
} from '../../utils/messages.js';
import {
exitWithError,
getSuccessNextActions,
printNextActions,
} from '../../utils/exit.js';

const context = msg('access-keys', 'create');

Expand All @@ -25,7 +30,7 @@ export default async function create(options: Record<string, unknown>) {

if (!name) {
printFailure(context, 'Access key name is required');
process.exit(1);
exitWithError('Access key name is required', context);
}

const loginMethod = await getLoginMethod();
Expand All @@ -35,15 +40,21 @@ export default async function create(options: Record<string, unknown>) {
context,
'Access keys can only be created when logged in via OAuth.\nRun "tigris login oauth" first.'
);
process.exit(1);
exitWithError(
'Access keys can only be created when logged in via OAuth.\nRun "tigris login oauth" first.',
context
);
}

const authClient = getAuthClient();
const isAuthenticated = await authClient.isAuthenticated();

if (!isAuthenticated) {
printFailure(context, 'Not authenticated. Run "tigris login oauth" first.');
process.exit(1);
exitWithError(
'Not authenticated. Run "tigris login oauth" first.',
context
);
}

const accessToken = await authClient.getAccessToken();
Expand All @@ -60,18 +71,22 @@ export default async function create(options: Record<string, unknown>) {

if (error) {
printFailure(context, error.message);
process.exit(1);
exitWithError(error, context);
}

if (format === 'json') {
console.log(
JSON.stringify({
action: 'created',
name: data.name,
id: data.id,
secret: data.secret,
})
);
const nextActions = getSuccessNextActions(context, {
name: data.name,
id: data.id,
});
const output: Record<string, unknown> = {
action: 'created',
name: data.name,
id: data.id,
secret: data.secret,
};
if (nextActions.length > 0) output.nextActions = nextActions;
console.log(JSON.stringify(output));
} else {
console.log(` Name: ${data.name}`);
console.log(` Access Key ID: ${data.id}`);
Expand All @@ -83,4 +98,5 @@ export default async function create(options: Record<string, unknown>) {
}

printSuccess(context);
printNextActions(context, { name: data.name, id: data.id });
}
15 changes: 11 additions & 4 deletions src/lib/access-keys/delete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
printFailure,
msg,
} from '../../utils/messages.js';
import { exitWithError } from '../../utils/exit.js';
import { requireInteractive, confirm } from '../../utils/interactive.js';

const context = msg('access-keys', 'delete');
Expand All @@ -27,7 +28,7 @@ export default async function remove(options: Record<string, unknown>) {

if (!id) {
printFailure(context, 'Access key ID is required');
process.exit(1);
exitWithError('Access key ID is required', context);
}

const loginMethod = await getLoginMethod();
Expand All @@ -37,15 +38,21 @@ export default async function remove(options: Record<string, unknown>) {
context,
'Access keys can only be deleted when logged in via OAuth.\nRun "tigris login oauth" first.'
);
process.exit(1);
exitWithError(
'Access keys can only be deleted when logged in via OAuth.\nRun "tigris login oauth" first.',
context
);
}

const authClient = getAuthClient();
const isAuthenticated = await authClient.isAuthenticated();

if (!isAuthenticated) {
printFailure(context, 'Not authenticated. Run "tigris login oauth" first.');
process.exit(1);
exitWithError(
'Not authenticated. Run "tigris login oauth" first.',
context
);
}

if (!force) {
Expand All @@ -71,7 +78,7 @@ export default async function remove(options: Record<string, unknown>) {

if (error) {
printFailure(context, error.message);
process.exit(1);
exitWithError(error, context);
}

if (format === 'json') {
Expand Down
15 changes: 11 additions & 4 deletions src/lib/access-keys/get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
printFailure,
msg,
} from '../../utils/messages.js';
import { exitWithError } from '../../utils/exit.js';

const context = msg('access-keys', 'get');

Expand All @@ -25,7 +26,7 @@ export default async function get(options: Record<string, unknown>) {

if (!id) {
printFailure(context, 'Access key ID is required');
process.exit(1);
exitWithError('Access key ID is required', context);
}

const loginMethod = await getLoginMethod();
Expand All @@ -35,15 +36,21 @@ export default async function get(options: Record<string, unknown>) {
context,
'Access keys can only be retrieved when logged in via OAuth.\nRun "tigris login oauth" first.'
);
process.exit(1);
exitWithError(
'Access keys can only be retrieved when logged in via OAuth.\nRun "tigris login oauth" first.',
context
);
}

const authClient = getAuthClient();
const isAuthenticated = await authClient.isAuthenticated();

if (!isAuthenticated) {
printFailure(context, 'Not authenticated. Run "tigris login oauth" first.');
process.exit(1);
exitWithError(
'Not authenticated. Run "tigris login oauth" first.',
context
);
}

const accessToken = await authClient.getAccessToken();
Expand All @@ -60,7 +67,7 @@ export default async function get(options: Record<string, unknown>) {

if (error) {
printFailure(context, error.message);
process.exit(1);
exitWithError(error, context);
}

if (format === 'json') {
Expand Down
Loading
Loading