npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@sf-explorer/soql-to-graphql

v0.2.0

Published

Transform your SOQL queries into GraphQL

Downloads

37

Readme

SOQL to GraphQL

npm version CI Test Coverage Security Audit License: MIT Downloads

🚀 Transform your SOQL queries into GraphQL with zero learning curve

logo

Are you a Salesforce developer struggling with GraphQL syntax? Already an SOQL ninja 🥷🏿? This library is your bridge between the familiar SOQL world and the powerful GraphQL ecosystem.

Perfect for:

  • Salesforce developers migrating to GraphQL
  • Teams building modern APIs with Salesforce data
  • Developers who want to leverage GraphQL without learning new syntax
  • Projects requiring type-safe, efficient data queries

📋 Table of Contents

✨ Features

  • 🔄 Seamless Conversion: Convert any SOQL query to GraphQL instantly
  • 🎯 Type Safety: Full TypeScript support with comprehensive type
  • 🧪 Battle Tested: Comprehensive test suite with 104+ test cases
  • 🔧 Developer Friendly: Excellent error messages and debugging support
  • 📚 Well Documented: Extensive documentation and examples
  • Real-time: Supports dynamic queries with variable binding

🎯 Quick Start

📦 Installation

npm

npm install @sf-explorer/soql-to-graphql

yarn

yarn add @sf-explorer/soql-to-graphql

pnpm

pnpm add @sf-explorer/soql-to-graphql

CDN (Browser)

<script src="https://unpkg.com/@sf-explorer/soql-to-graphql@latest/dist/index.js"></script>

Requirements

  • Node.js 18.x or higher
  • TypeScript 5.x (optional, for type definitions)

🚀 Usage

Basic Example

import soql2graphql from '@sf-explorer/soql-to-graphql';

// Simple SOQL query
const soql = 'SELECT Id, Name FROM Account LIMIT 5';
const graphql = soql2graphql(soql);

console.log(graphql);

Output:

query {
  uiapi {
    query {
      Account(first: 5) {
        edges {
          node {
            Id
            Name {
              value
            }
          }
        }
      }
    }
  }
}

Advanced Queries with Relationships

const soql = `
  SELECT Id, Name, Owner.Name, 
         (SELECT Id, Name, Amount FROM Opportunities WHERE StageName = 'Closed Won')
  FROM Account 
  WHERE Industry = 'Technology' 
  ORDER BY Name ASC 
  LIMIT 10
`;

const graphql = soql2graphql(soql);

Output:

query {
  uiapi {
    query {
      Account(
        first: 10
        where: { Industry: { eq: "Technology" } }
        orderBy: { Name: { order: ASC } }
      ) {
        edges {
          node {
            Id
            Name {
              value
            }
            Owner {
              Name {
                value
              }
            }
            Opportunities(where: { StageName: { eq: "Closed Won" } }) {
              edges {
                node {
                  Id
                  Name {
                    value
                  }
                  Amount {
                    value
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

Dynamic Queries with Variables

const soql = `
  SELECT Id, Name, Email 
  FROM Contact 
  WHERE AccountId = :accountId 
    AND IsActive = :isActive
  ORDER BY Name ASC
`;

const variables = {
  accountId: 'ID!',
  isActive: 'Boolean',
};

const graphql = soql2graphql(soql, variables);

Output:

query ($accountId: ID!, $isActive: Boolean) {
  uiapi {
    query {
      Contact(
        where: {
          and: [
            { AccountId: { eq: $accountId } }
            { IsActive: { eq: $isActive } }
          ]
        }
        orderBy: { Name: { order: ASC } }
      ) {
        edges {
          node {
            Id
            Name {
              value
            }
            Email {
              value
            }
          }
        }
      }
    }
  }
}

Complex WHERE Conditions

const soql = `
  SELECT Id, Name, Amount, StageName
  FROM Opportunity
  WHERE (Amount > 10000 AND StageName = 'Closed Won')
     OR (Amount > 5000 AND StageName = 'Prospecting')
  ORDER BY Amount DESC
  LIMIT 20
`;

const graphql = soql2graphql(soql);

Output:

query {
  uiapi {
    query {
      Opportunity(
        first: 20
        where: {
          or: [
            {
              and: [
                { Amount: { gt: 10000 } }
                { StageName: { eq: "Closed Won" } }
              ]
            }
            {
              and: [
                { Amount: { gt: 5000 } }
                { StageName: { eq: "Prospecting" } }
              ]
            }
          ]
        }
        orderBy: { Amount: { order: DESC } }
      ) {
        edges {
          node {
            Id
            Name {
              value
            }
            Amount {
              value
            }
            StageName {
              value
            }
          }
        }
      }
    }
  }
}

📚 API Documentation

soql2graphql(soql: string, variables?: VariableDefinitions): string

Converts a SOQL query string to GraphQL format.

Parameters

  • soql (string, required): The SOQL query to convert
  • variables (VariableDefinitions, optional): Variable definitions for bind variables

Returns

  • string: The generated GraphQL query

Example

import soql2graphql, {
  VariableDefinitions,
} from '@sf-explorer/soql-to-graphql';

const soql = 'SELECT Id FROM Account WHERE Name = :name';
const variables: VariableDefinitions = { name: 'String' };
const graphql = soql2graphql(soql, variables);

Type Definitions

interface VariableDefinitions {
  [prop: string]: string;
}

type ComparisonOperator =
  | 'eq'
  | 'ne'
  | 'like'
  | 'in'
  | 'gt'
  | 'gte'
  | 'lt'
  | 'lte';
type LogicalOperator = 'and' | 'or';
type OrderDirection = 'ASC' | 'DESC';

Supported SOQL Features

| Feature | Status | Example | | -------------------- | ------ | -------------------------------------------------------- | | Basic SELECT | ✅ | SELECT Id, Name FROM Account | | WHERE clauses | ✅ | WHERE Name = 'Test' | | ORDER BY | ✅ | ORDER BY Name ASC | | LIMIT | ✅ | LIMIT 10 | | Relationships | ✅ | SELECT Owner.Name FROM Account | | Subqueries | ✅ | SELECT Id, (SELECT Id FROM Opportunities) FROM Account | | Variable binding | ✅ | WHERE Name = :name | | Logical operators | ✅ | WHERE A = 1 AND B = 2 | | Comparison operators | ✅ | WHERE Amount > 1000 | | IN clauses | ✅ | WHERE Id IN ('001', '002') | | LIKE patterns | ✅ | WHERE Name LIKE '%Test%' | | Functions | ✅ | SELECT COUNT(Id) FROM Account |

🔧 Configuration

Environment Variables

# Optional: Set custom GraphQL endpoint
GRAPHQL_ENDPOINT=https://your-instance.salesforce.com/graphql

# Optional: Enable debug mode
DEBUG=soql-to-graphql

Error Handling

try {
  const graphql = soql2graphql(invalidSoql);
} catch (error) {
  console.error('Conversion failed:', error.message);
  // Handle error appropriately
}

🛠️ Troubleshooting

Common Issues

"Invalid SOQL query" Error

// ❌ Incorrect
const soql = 'SELECT Id FROM'; // Missing table name

// ✅ Correct
const soql = 'SELECT Id FROM Account';

Variable Binding Issues

// ❌ Incorrect
const soql = 'SELECT Id FROM Account WHERE Name = :name';
const variables = { name: 'John' }; // Missing type definition

// ✅ Correct
const soql = 'SELECT Id FROM Account WHERE Name = :name';
const variables = { name: 'String' }; // Include type

Complex WHERE Conditions

// ❌ Incorrect - Missing parentheses
const soql = 'SELECT Id FROM Account WHERE A = 1 AND B = 2 OR C = 3';

// ✅ Correct - Proper grouping
const soql = 'SELECT Id FROM Account WHERE (A = 1 AND B = 2) OR C = 3';

Debug Mode

Enable debug mode to see detailed conversion information:

process.env.DEBUG = 'soql-to-graphql';
const graphql = soql2graphql(soql);

Getting Help

  1. Check the Issues for known problems
  2. Create a new issue with:
    • Your SOQL query
    • Expected vs actual output
    • Error messages
    • Environment details

FAQ

Q: Can I use this with any GraphQL client? A: Yes! The output is standard GraphQL that works with any client.

Q: Does this support all SOQL features? A: We support the most common SOQL features. Check the supported features table.

Q: How do I handle custom fields? A: Custom fields work the same as standard fields. Just use the API name: SELECT Custom_Field__c FROM Account.

Q: Can I convert multiple queries at once? A: Currently, you need to convert each query individually, but you can batch the calls for efficiency.

🛠️ Development

Prerequisites

  • Node.js 18.x or higher
  • npm 8.x or higher
  • Git

Quick Setup

# Clone the repository
git clone https://github.com/sf-explorer/soql-to-graphql.git
cd soql-to-graphql

# Install dependencies
npm install

# Run the development server
npm run dev

# Run tests in watch mode
npm run test:watch

Available Scripts

| Script | Description | | --------------------- | ----------------------------------- | | npm run build | Build the project for production | | npm run build:watch | Build in watch mode for development | | npm run test | Run the complete test suite | | npm run test:watch | Run tests in watch mode | | npm run test:ci | Run tests for CI environment | | npm run lint | Run ESLint code quality checks | | npm run lint:fix | Fix ESLint issues automatically | | npm run prettier | Format code with Prettier | | npm run type-check | Run TypeScript type checking | | npm run ci | Run complete CI pipeline locally |

Project Structure

src/
├── types.ts           # TypeScript type definitions
├── constants.ts       # Application constants
├── operators.ts       # SOQL operator conversion logic
├── whereConverter.ts  # WHERE clause conversion
├── fieldConverter.ts  # Field conversion logic
├── queryConverter.ts  # Main query conversion
├── converter.ts       # Main entry point
└── main.ts           # Public API

__test__/
├── unit/              # Unit tests for individual modules
├── integration/       # End-to-end integration tests

└── fixtures/          # Test data and fixtures

Testing Strategy

The project includes comprehensive testing with 96%+ coverage:

  • 🧪 Unit Tests: Individual module testing

  • 🔗 Integration Tests: End-to-end functionality

  • 🛡️ Error Handling: Edge cases and error scenarios

  • 📊 Coverage Reports: Detailed coverage analysis

Code Quality

  • ESLint: Code quality and style enforcement
  • Prettier: Consistent code formatting
  • TypeScript: Type safety and IntelliSense
  • Husky: Git hooks for quality gates
  • Jest: Comprehensive testing framework

Git Hooks

This project uses Git hooks to ensure code quality:

  • Pre-commit: Automatically formats and lints staged files
  • Pre-push: Verifies all files are properly formatted before push

See Git Hooks Documentation for detailed information.

Contributing Guidelines

We welcome contributions! Here's how to get started:

1. Fork and Clone

git clone https://github.com/YOUR_USERNAME/soql-to-graphql.git
cd soql-to-graphql

2. Create a Feature Branch

git checkout -b feature/your-feature-name

3. Make Your Changes

  • Write clean, well-documented code
  • Add tests for new functionality
  • Update documentation as needed
  • Follow the existing code style

4. Test Your Changes

npm run ci  # Run complete CI pipeline

5. Submit a Pull Request

  • Provide a clear description of your changes
  • Reference any related issues
  • Ensure all CI checks pass

CI/CD Pipeline

Our GitHub Actions workflow ensures code quality:

  • 🔄 Continuous Integration: Runs on every push and PR
  • 🔒 Security Audits: Automated vulnerability scanning
  • 📦 Dependency Updates: Weekly automated updates
  • 🚀 Release Automation: Automated versioning and publishing
  • 📊 Coverage Reporting: Code coverage tracking

Release Process

We use automated releases with GitHub Actions:

  1. Trigger Release: Use GitHub Actions workflow or create a git tag
  2. Automated Testing: All tests run automatically
  3. Version Update: Version number incremented automatically
  4. NPM Publishing: Package published to NPM automatically
  5. GitHub Release: Release notes and changelog generated

Quick Release Commands:

# Patch release (bug fixes)
npm run version:patch

# Minor release (new features)
npm run version:minor

# Major release (breaking changes)
npm run version:major

See Release Guide for detailed instructions.

📄 License

This project is licensed under the MIT License - a permissive open-source license that allows you to:

What You Can Do

  • Use commercially - Use in commercial projects and products
  • Modify - Change the code to fit your needs
  • Distribute - Share the code with others
  • Sublicense - Include in your own projects with different licenses
  • Private use - Use in private projects without restrictions

📋 License Requirements

  • Include the license - Keep the MIT license text in your distribution
  • Include copyright - Maintain the copyright notice
  • No warranty - The software is provided "as is" without warranty

🔗 Full License Text

See the complete LICENSE file for the full legal text.

💡 Why MIT?

The MIT License was chosen because it:

  • Maximizes adoption - Easy for businesses to use
  • Minimal restrictions - Simple and permissive
  • Industry standard - Widely recognized and trusted
  • Developer friendly - Clear and easy to understand

🤝 Support

🙏 Credits

This utility would be nothing without these powerful libraries:

⭐ Star History

Star History Chart