A safe SOQL template literal tag for escaping values in Salesforce SOQL queries.
npm install @niicojs/soqlUse the soql template tag to safely interpolate values into your SOQL queries:
import { soql } from '@niicojs/soql';
const name = "O'Brien";
const query = soql`SELECT Id FROM Account WHERE Name = ${name}`;
// → SELECT Id FROM Account WHERE Name = 'O\'Brien'The soql tag automatically handles escaping for various types:
// Strings - automatically quoted and escaped
const name = 'Acme Corp';
soql`SELECT Id FROM Account WHERE Name = ${name}`;
// → SELECT Id FROM Account WHERE Name = 'Acme Corp'
// Numbers
const amount = 1000.5;
soql`SELECT Id FROM Account WHERE Amount__c > ${amount}`;
// → SELECT Id FROM Account WHERE Amount__c > 1000.5
// Booleans
const isActive = true;
soql`SELECT Id FROM Account WHERE IsActive = ${isActive}`;
// → SELECT Id FROM Account WHERE IsActive = true
// null
soql`SELECT Id FROM Account WHERE Parent = ${null}`;
// → SELECT Id FROM Account WHERE Parent = null
// Dates (formatted as datetime by default)
const d = new Date('2024-03-15T14:30:45.000Z');
soql`SELECT Id FROM Account WHERE CreatedDate > ${d}`;
// → SELECT Id FROM Account WHERE CreatedDate > 2024-03-15T14:30:45Z
// Arrays (for IN clauses)
const ids = ['001xx1', '001xx2', '001xx3'];
soql`SELECT Id FROM Account WHERE Id IN ${ids}`;
// → SELECT Id FROM Account WHERE Id IN ('001xx1', '001xx2', '001xx3')Use raw() for trusted field names or other unescaped values:
import { soql, raw } from '@niicojs/soql';
const field = raw('Custom_Field__c');
soql`SELECT ${field} FROM Account`;
// → SELECT Custom_Field__c FROM AccountWarning: Only use raw() with trusted values. User input passed to raw() could enable SOQL injection.
Use like() for LIKE clause patterns - it escapes special LIKE characters (%, _):
import { soql, like } from '@niicojs/soql';
const search = like('%test%');
soql`SELECT Id FROM Account WHERE Name LIKE ${search}`;
// → SELECT Id FROM Account WHERE Name LIKE '\%test\%'Use date() to force date-only formatting (YYYY-MM-DD) instead of datetime:
import { soql, date } from '@niicojs/soql';
const d = new Date('2024-03-15T14:30:45.000Z');
soql`SELECT Id FROM Contact WHERE Birthdate = ${date(d)}`;
// → SELECT Id FROM Contact WHERE Birthdate = 2024-03-15Use literal() for SOQL date literals like TODAY, YESTERDAY, LAST_N_DAYS:n, etc.:
import { soql, literal } from '@niicojs/soql';
soql`SELECT Id FROM Account WHERE CreatedDate > ${literal('YESTERDAY')}`;
// → SELECT Id FROM Account WHERE CreatedDate > YESTERDAY
soql`SELECT Id FROM Account WHERE CreatedDate > ${literal('LAST_N_DAYS:30')}`;
// → SELECT Id FROM Account WHERE CreatedDate > LAST_N_DAYS:30Supported date literals include:
TODAY,YESTERDAY,TOMORROWLAST_WEEK,THIS_WEEK,NEXT_WEEKLAST_MONTH,THIS_MONTH,NEXT_MONTHLAST_90_DAYS,NEXT_90_DAYSTHIS_QUARTER,LAST_QUARTER,NEXT_QUARTERTHIS_YEAR,LAST_YEAR,NEXT_YEARTHIS_FISCAL_QUARTER,LAST_FISCAL_QUARTER,NEXT_FISCAL_QUARTERTHIS_FISCAL_YEAR,LAST_FISCAL_YEAR,NEXT_FISCAL_YEARLAST_N_DAYS:n,NEXT_N_DAYS:nLAST_N_WEEKS:n,NEXT_N_WEEKS:nLAST_N_MONTHS:n,NEXT_N_MONTHS:nLAST_N_QUARTERS:n,NEXT_N_QUARTERS:nLAST_N_YEARS:n,NEXT_N_YEARS:n- And fiscal variants...
Use join() to build dynamic field lists or conditions:
import { soql, raw, join } from '@niicojs/soql';
// Dynamic field selection
const fields = ['Id', 'Name', 'Email'].map((f) => raw(f));
soql`SELECT ${join(fields)} FROM Contact`;
// → SELECT Id, Name, Email FROM Contact
// Dynamic conditions
const conditions = [raw('IsActive = true'), raw("Type = 'Customer'")];
soql`SELECT Id FROM Account WHERE ${join(conditions, ' AND ')}`;
// → SELECT Id FROM Account WHERE IsActive = true AND Type = 'Customer'The library automatically escapes dangerous characters to prevent SOQL injection:
const malicious = "'; DELETE FROM Account; --";
soql`SELECT Id FROM Account WHERE Name = ${malicious}`;
// → SELECT Id FROM Account WHERE Name = '\'; DELETE FROM Account; --'Empty arrays in IN clauses will throw an error, as this is typically a programming mistake:
const ids: string[] = [];
soql`SELECT Id FROM Account WHERE Id IN ${ids}`;
// → Throws: "Empty arrays are not allowed in SOQL IN clauses..."Handle this by checking the array before building the query:
if (ids.length > 0) {
const query = soql`SELECT Id FROM Account WHERE Id IN ${ids}`;
// execute query
}Tagged template literal for creating safe SOQL queries.
const query = soql`SELECT Id FROM ${raw('Account')} WHERE Name = ${name}`;Creates a raw (unescaped) value. Use for trusted field names, object names, etc.
Creates a LIKE pattern value with special escaping for LIKE wildcards.
Creates a date-only value (formats as YYYY-MM-DD instead of datetime).
Creates a SOQL date literal value (TODAY, LAST_N_DAYS:n, etc.).
Joins multiple values with a separator (default: ', ').
For advanced use cases, individual escape functions are exported:
import {
escapeString, // Escape a string value
escapeLike, // Escape a LIKE pattern value
escapeValue, // Escape any supported value type
escapeArray, // Escape an array for IN clauses
formatDate, // Format Date as YYYY-MM-DD
formatDateTime, // Format Date as YYYY-MM-DDThh:mm:ssZ
} from '@niicojs/soql';import type {
SoqlValue, // Union of all supported value types
RawValue, // Raw (unescaped) value marker
LikeValue, // LIKE pattern value marker
DateValue, // Date-only value marker
DateLiteral, // SOQL date literal types
} from '@niicojs/soql';For advanced type checking, the internal symbols are exported:
import { RAW_SYMBOL, LIKE_SYMBOL, DATE_SYMBOL } from '@niicojs/soql';- Node.js >= 20
MIT