Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
4 changes: 2 additions & 2 deletions src/bin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2407,10 +2407,10 @@ yargs(rawArgs)
}),
async (argv) => {
await applyInsecureStorage(argv.insecureStorage);
const { resolveApiKey } = await import('./lib/api-key.js');
const { resolveOptionalApiKey } = await import('./lib/api-key.js');
const { getMigrationsPassthroughArgs, runMigrations } = await import('./commands/migrations.js');
const passthrough = getMigrationsPassthroughArgs(rawArgs);
await runMigrations(passthrough, resolveApiKey({ apiKey: argv.apiKey }));
await runMigrations(passthrough, resolveOptionalApiKey({ apiKey: argv.apiKey }));
},
)
.command(
Expand Down
6 changes: 6 additions & 0 deletions src/commands/migrations.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ describe('runMigrations', () => {
expect(process.env.WORKOS_SECRET_KEY).toBe('sk_test_123');
});

it('does not require WORKOS_SECRET_KEY when no API key is provided', async () => {
await runMigrations(['wizard']);
expect(process.env.WORKOS_SECRET_KEY).toBeUndefined();
expect(mockParseAsync).toHaveBeenCalledWith(['wizard'], { from: 'user' });
});

it('delegates to Commander parseAsync with correct args', async () => {
await runMigrations(['import', '--csv', 'users.csv'], 'sk_test_123');
expect(mockParseAsync).toHaveBeenCalledWith(['import', '--csv', 'users.csv'], { from: 'user' });
Expand Down
6 changes: 4 additions & 2 deletions src/commands/migrations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,10 @@ export function getMigrationsPassthroughArgs(rawArgs: string[]): string[] {
return passthrough;
}

export async function runMigrations(args: string[], apiKey: string): Promise<void> {
process.env.WORKOS_SECRET_KEY = apiKey;
export async function runMigrations(args: string[], apiKey?: string): Promise<void> {
if (apiKey) {
process.env.WORKOS_SECRET_KEY = apiKey;
}

const { program } = (await import('@workos/migrations/dist/cli/index.js')) as {
program: {
Expand Down
18 changes: 17 additions & 1 deletion src/lib/api-key.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ vi.mock('node:os', async (importOriginal) => {
});

const { saveConfig, setInsecureConfigStorage, clearConfig } = await import('./config-store.js');
const { resolveApiKey, resolveApiBaseUrl } = await import('./api-key.js');
const { resolveApiKey, resolveOptionalApiKey, resolveApiBaseUrl } = await import('./api-key.js');

describe('api-key', () => {
const originalEnv = process.env;
Expand Down Expand Up @@ -117,6 +117,22 @@ describe('api-key', () => {
});
});

describe('resolveOptionalApiKey', () => {
it('returns undefined when no API key is available', () => {
mockExitWithError.mockClear();
expect(resolveOptionalApiKey()).toBeUndefined();
expect(mockExitWithError).not.toHaveBeenCalled();
});

it('returns configured API key when available', () => {
saveConfig({
activeEnvironment: 'prod',
environments: { prod: { name: 'prod', type: 'production', apiKey: 'sk_stored' } },
});
expect(resolveOptionalApiKey()).toBe('sk_stored');
});
});
Comment thread
greptile-apps[bot] marked this conversation as resolved.

describe('resolveApiBaseUrl', () => {
it('returns default URL when no config', () => {
expect(resolveApiBaseUrl()).toBe('https://api.workos.com');
Expand Down
15 changes: 11 additions & 4 deletions src/lib/api-key.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,16 @@ export interface ApiKeyOptions {
}

export function resolveApiKey(options?: ApiKeyOptions): string {
const apiKey = resolveOptionalApiKey(options);
if (apiKey) return apiKey;

exitWithError({
code: 'no_api_key',
message: 'No API key configured. Run `workos env add` to configure an environment, or set WORKOS_API_KEY.',
});
}

export function resolveOptionalApiKey(options?: ApiKeyOptions): string | undefined {
if (options?.apiKey) return options.apiKey;

const envVar = process.env.WORKOS_API_KEY;
Expand All @@ -25,10 +35,7 @@ export function resolveApiKey(options?: ApiKeyOptions): string {
const activeEnv = getActiveEnvironment();
if (activeEnv?.apiKey) return activeEnv.apiKey;

exitWithError({
code: 'no_api_key',
message: 'No API key configured. Run `workos env add` to configure an environment, or set WORKOS_API_KEY.',
});
return undefined;
}

export function resolveApiBaseUrl(): string {
Expand Down
Loading