/

Turso Database Querying

Copy script

Copied

Copy script

Copied

Turso Database Querying

Created by

andrew van beek - Keyboard Team

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.

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');
}

ยฉ 2025 Keyboard.dev. All rights reserved.

ยฉ 2025 Keyboard.dev. All rights reserved.