Skip to content

Commit 5b4a515

Browse files
committed
add support for nile auth env and nile local connect
1 parent 48d24de commit 5b4a515

2 files changed

Lines changed: 140 additions & 1 deletion

File tree

src/commands/auth.ts

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,66 @@ export function createAuthCommand(getOptions: GetOptions): Command {
4141
.addHelpText('after', `
4242
Examples:
4343
${formatCommand('nile auth quickstart --nextjs')} Create a Next.js app with Nile auth
44+
${formatCommand('nile auth env')} Generate Nile environment variables
4445
4546
${getGlobalOptionsHelp()}`);
4647

48+
auth
49+
.command('env')
50+
.description('Generate Nile environment variables')
51+
.option('--output <file>', 'Output to a file (e.g. .env.local)')
52+
.action(async (cmdOptions) => {
53+
try {
54+
const step = ora({
55+
text: 'Fetching credentials from Nile...',
56+
color: 'yellow'
57+
}).start();
58+
59+
try {
60+
const options = getOptions();
61+
const configManager = new ConfigManager(options);
62+
const api = new NileAPI({
63+
token: configManager.getToken(),
64+
dbHost: configManager.getDbHost(),
65+
controlPlaneUrl: configManager.getGlobalHost(),
66+
});
67+
68+
const { workspaceSlug, databaseName } = await getWorkspaceAndDatabase(options);
69+
const credentials = await api.createDatabaseCredentials(workspaceSlug, databaseName);
70+
const database = await api.getDatabase(workspaceSlug, databaseName);
71+
72+
step.succeed('Received credentials from Nile database');
73+
await sleep(300);
74+
75+
const envContent = `NILEDB_USER=${credentials.id}
76+
NILEDB_PASSWORD=${credentials.password}
77+
NILEDB_API_URL=https://us-west-2.api.thenile.dev/v2/databases/${database.id}
78+
NILEDB_POSTGRES_URL=postgres://us-west-2.db.thenile.dev:5432/${databaseName}`;
79+
80+
if (cmdOptions.output) {
81+
await fs.writeFile(cmdOptions.output, envContent);
82+
console.log(styles.success(`\n✓ Environment variables written to ${cmdOptions.output}`));
83+
} else {
84+
console.log(styles.info('\nNile Environment Variables:'));
85+
console.log(styles.info('```env'));
86+
console.log(envContent);
87+
console.log(styles.info('```'));
88+
console.log(styles.info('\nTo save these variables to a file, use --output flag:'));
89+
console.log(styles.command('nile auth env --output .env.local'));
90+
}
91+
} catch (error: any) {
92+
step.fail('Failed to generate environment variables');
93+
if (getOptions().debug) {
94+
console.error(theme.error('Error details:'), error.message);
95+
}
96+
process.exit(1);
97+
}
98+
} catch (error: any) {
99+
console.error(theme.error('\nFailed to generate environment variables:'), error.message || 'Unknown error');
100+
process.exit(1);
101+
}
102+
});
103+
47104
auth
48105
.command('quickstart')
49106
.description('Set up a new application with Nile authentication')

src/commands/local.ts

Lines changed: 83 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ Examples:
4343
${formatCommand('nile local start', '--no-prompt')} Start without prompting for psql connection
4444
${formatCommand('nile local stop')} Stop local development environment
4545
${formatCommand('nile local info')} Show connection information
46-
46+
${formatCommand('nile local connect --psql')} Connect to local database using psql
47+
4748
${getGlobalOptionsHelp()}`);
4849

4950
local
@@ -314,5 +315,86 @@ ${getGlobalOptionsHelp()}`);
314315
}
315316
});
316317

318+
local
319+
.command('connect')
320+
.description('Connect to local database')
321+
.requiredOption('--psql', 'Connect using PostgreSQL CLI')
322+
.action(async (cmdOptions) => {
323+
try {
324+
// Check if container is running
325+
const { stdout } = await execAsync('docker ps --filter name=nile-local --format {{.Names}}');
326+
if (!stdout.includes('nile-local')) {
327+
console.error(theme.error('\nNo Nile local environment is currently running.'));
328+
console.log(theme.dim('Start it with: nile local start'));
329+
process.exit(1);
330+
}
331+
332+
const connectSpinner = ora({
333+
text: 'Connecting to local database...',
334+
color: 'cyan'
335+
}).start();
336+
337+
try {
338+
// Add a delay to ensure the database is ready for connections
339+
await new Promise(resolve => setTimeout(resolve, 1000));
340+
341+
// Connect using psql with individual parameters
342+
const psql = spawn('psql', [
343+
'-h', 'localhost',
344+
'-p', '5432',
345+
'-U', '00000000-0000-0000-0000-000000000000',
346+
'-d', 'test',
347+
'-w' // Never prompt for password
348+
], {
349+
stdio: 'inherit',
350+
env: {
351+
...process.env,
352+
PGPASSWORD: 'password' // Set password via environment variable
353+
}
354+
});
355+
356+
// Stop the spinner immediately as psql will take over the terminal
357+
connectSpinner.stop();
358+
359+
// Handle psql exit
360+
psql.on('exit', (code) => {
361+
if (code !== 0) {
362+
console.error(theme.error('\nFailed to connect using psql. Please check if psql is installed.'));
363+
if (getOptions().debug) {
364+
console.error(theme.dim('Try connecting directly with:'));
365+
console.error(theme.dim('PGPASSWORD=password psql -h localhost -p 5432 -U 00000000-0000-0000-0000-000000000000 -d test'));
366+
}
367+
process.exit(1);
368+
}
369+
});
370+
371+
// Handle psql error
372+
psql.on('error', (error) => {
373+
connectSpinner.fail('Failed to launch psql');
374+
console.error(theme.error('\nError launching psql:'), error.message);
375+
if (error.message.includes('ENOENT')) {
376+
console.error(theme.error('Please make sure psql is installed and available in your PATH'));
377+
}
378+
process.exit(1);
379+
});
380+
381+
} catch (error: any) {
382+
connectSpinner.fail('Failed to connect to database');
383+
if (getOptions().debug) {
384+
console.error(theme.error('Error details:'), error.message);
385+
}
386+
process.exit(1);
387+
}
388+
} catch (error: any) {
389+
const options = getOptions();
390+
if (options.debug) {
391+
console.error(theme.error('\nFailed to connect to database:'), error);
392+
} else {
393+
console.error(theme.error('\nFailed to connect to database:'), error.message || 'Unknown error');
394+
}
395+
process.exit(1);
396+
}
397+
});
398+
317399
return local;
318400
}

0 commit comments

Comments
 (0)