/

Turso Database Querying

Copy script

Copied

Copy script

Copied

Turso Database Querying

Complete solution for querying Turso databases using Platform API token to generate database-specific tokens. Demonstrates proper authentication workflow: Platform API → Database Token → Query Data. Lists all databases, creates proper tokens, and queries table data with sample results. Perfect for developers working with Turso/LibSQL databases who need to understand the correct authentication flow.

Created by

andrew van beek - Keyboard Team

Requirements

turso.tech logo

KEYBOARD_TURSO_DATABASE_TOKEN

Script

Copy script

Copied

Copy script

Copied

const axios = require('axios');
const { createClient } = require('@libsql/client');

console.log('šŸ”§ Turso Database Query with Proper Authentication');
console.log('===================================================\n');

const platformToken = process.env.KEYBOARD_TURSO_DATABASE_TOKEN;
if (!platformToken) {
  console.error('āŒ KEYBOARD_TURSO_DATABASE_TOKEN environment variable not found');
  console.error('Please ensure your Platform API token is properly configured');
  return;
}

// Configuration from variables
const maxRows = {{maxRowsPerTable}} || 5;
const showSchema = {{showTableSchema}} !== false;
const targetOrg = '{{organizationName}}' || null;
const targetDb = '{{databaseName}}' || null;

try {
  // Step 1: Get user information
  console.log('šŸ” Step 1: Authenticating with Platform API...');
  const userResponse = await axios.get('https://api.turso.tech/v1/current-user', {
    headers: { 'Authorization': `Bearer ${platformToken}` }
  });
  
  const username = userResponse.data.user.username;
  const orgToUse = targetOrg || username;
  
  console.log(`āœ… Platform API access successful!`);
  console.log(`šŸ‘¤ User: ${userResponse.data.user.name} (@${username})`);
  console.log(`šŸ“§ Email: ${userResponse.data.user.email}`);
  console.log(`šŸ¢ Using organization: ${orgToUse}\n`);
  
  // Step 2: List databases
  console.log('šŸ“Š Step 2: Listing available databases...');
  const dbResponse = await axios.get(`https://api.turso.tech/v1/organizations/${orgToUse}/databases`, {
    headers: { 'Authorization': `Bearer ${platformToken}` }
  });
  
  const databases = dbResponse.data.databases;
  console.log(`āœ… Found ${databases.length} database(s):`);
  
  databases.forEach((db, index) => {
    console.log(`   ${index + 1}. ${db.Name} (${db.regions.join(', ')})`);
  });
  
  if (databases.length === 0) {
    console.log('āŒ No databases found in organization');
    return;
  }
  
  // Step 3: Select database to query
  let databaseToQuery;
  if (targetDb) {
    databaseToQuery = databases.find(db => db.Name === targetDb);
    if (!databaseToQuery) {
      console.log(`āŒ Database '${targetDb}' not found. Available databases:`);
      databases.forEach(db => console.log(`   • ${db.Name}`));
      return;
    }
  } else {
    databaseToQuery = databases[0]; // Use first database
  }
  
  console.log(`\nšŸŽÆ Selected database: ${databaseToQuery.Name}`);
  console.log(`   URL: libsql://${databaseToQuery.Hostname}`);
  console.log(`   Regions: ${databaseToQuery.regions.join(', ')}\n`);
  
  // Step 4: Generate database-specific token
  console.log('šŸ”‘ Step 3: Creating database-specific authentication token...');
  const tokenResponse = await axios.post(
    `https://api.turso.tech/v1/organizations/${orgToUse}/databases/${databaseToQuery.Name}/auth/tokens`,
    {},
    { headers: { 'Authorization': `Bearer ${platformToken}` } }
  );
  
  const databaseToken = tokenResponse.data.jwt;
  console.log('āœ… Database token generated successfully!\n');
  
  // Step 5: Connect and query database
  console.log('šŸ“Š Step 4: Connecting to database and querying data...');
  const client = createClient({
    url: `libsql://${databaseToQuery.Hostname}`,
    authToken: databaseToken
  });
  
  // List all user tables
  const tablesResult = await client.execute("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%';");
  
  console.log(`āœ… Database connection successful!`);
  console.log(`šŸ“‹ Found ${tablesResult.rows.length} user table(s):\n`);
  
  if (tablesResult.rows.length === 0) {
    console.log('   šŸ“ Database contains no user tables (empty database)');
  } else {
    // Query each table
    for (const tableRow of tablesResult.rows) {
      const tableName = tableRow.name;
      console.log(`šŸ—‚ļø  Table: ${tableName}`);
      
      try {
        // Get table schema if requested
        if (showSchema) {
          const schemaResult = await client.execute(`PRAGMA table_info("${tableName}");`);
          console.log(`   šŸ“ Schema:`);
          schemaResult.rows.forEach(col => {
            const nullable = col.notnull ? 'NOT NULL' : 'NULLABLE';
            const pk = col.pk ? ' (PRIMARY KEY)' : '';
            console.log(`      ${col.name}: ${col.type} ${nullable}${pk}`);
          });
        }
        
        // Get row count
        const countResult = await client.execute(`SELECT COUNT(*) as count FROM "${tableName}";`);
        const totalRows = countResult.rows[0].count;
        console.log(`   šŸ“Š Total rows: ${totalRows}`);
        
        if (totalRows > 0) {
          // Get sample data
          const dataResult = await client.execute(`SELECT * FROM "${tableName}" LIMIT ${maxRows};`);
          
          console.log(`   šŸ“„ Sample data (showing ${Math.min(dataResult.rows.length, maxRows)} of ${totalRows} rows):`);
          
          dataResult.rows.forEach((row, index) => {
            console.log(`      [${index + 1}] ${JSON.stringify(row)}`);
          });
          
          if (totalRows > maxRows) {
            console.log(`      ... and ${totalRows - maxRows} more rows`);
          }
        } else {
          console.log(`   šŸ“ Table is empty`);
        }
        
        console.log(''); // Add spacing between tables
        
      } catch (tableError) {
        console.log(`   āŒ Error querying table ${tableName}: ${tableError.message}\n`);
      }
    }
  }
  
  // Summary
  console.log('šŸŽ‰ Query completed successfully!\n');
  console.log('šŸ“Š Summary:');
  console.log(`   • Database: ${databaseToQuery.Name}`);
  console.log(`   • Tables found: ${tablesResult.rows.length}`);
  console.log(`   • Authentication: Platform API → Database Token → Query`);
  
  console.log('\nšŸ’” Key Points:');
  console.log('   āœ… Platform API token works for database management');
  console.log('   āœ… Database-specific tokens required for queries');
  console.log('   āœ… This is the correct and secure authentication flow');
  
} catch (error) {
  console.error('āŒ Error during execution:', error.response?.status || error.message);
  
  if (error.response?.data) {
    console.error('šŸ“‹ Error details:', JSON.stringify(error.response.data, null, 2));
  }
  
  console.error('\nšŸ”§ Troubleshooting:');
  console.error('   • Ensure KEYBOARD_TURSO_DATABASE_TOKEN is a valid Platform API token');
  console.error('   • Verify you have access to the specified organization/database');
  console.error('   • Check that the database exists and is not archived');
}