Escape functions provide safe handling of identifiers and values in SurrealQL queries when you need to construct queries manually.
!NOTE: Tip
Prefer usingsurqlorBoundQueryfor automatic parameterisation. Use escape functions only when absolutely necessary.
Import:
import {
escapeIdent,
escapeNumber,
escapeIdPart,
escapeRangeBound
} from 'surrealdb';Source: utils/escape.ts
Functions
escapeIdent(name)
Escape table names, field names, and other identifiers.
function escapeIdent(name: string): stringParameters
Parameter | Type | Description |
|---|---|---|
name | string | The identifier to escape. |
Returns
string - Escaped identifier
Examples
import { escapeIdent } from 'surrealdb';
// Simple identifiers (no escaping needed)
console.log(escapeIdent('users')); // 'users'
console.log(escapeIdent('first_name')); // 'first_name'
// Special characters (wrapped in backticks)
console.log(escapeIdent('user-table')); // '`user-table`'
console.log(escapeIdent('my table')); // '`my table`'
console.log(escapeIdent('user.name')); // '`user.name`'
// Reserved keywords
console.log(escapeIdent('select')); // '`select`'
console.log(escapeIdent('from')); // '`from`' escapeNumber(num)
Escape a number to be used as a valid SurrealQL ident.
function escapeNumber(num: number | bigint): stringParameters
Parameter | Type | Description |
|---|---|---|
num | number | bigint | The number to escape. |
Returns
string - Escaped number representation
Examples
import { escapeNumber } from 'surrealdb';
console.log(escapeNumber(123)); // '123'
console.log(escapeNumber(42n)); // '42' escapeIdPart(id)
Escape a record ID value part. Handles Uuid, string, number, bigint, and object values.
function escapeIdPart(id: RecordIdValue): stringParameters
Parameter | Type | Description |
|---|---|---|
id | RecordIdValue | The record ID value part to escape. |
Returns
string - Escaped record ID part
Examples
import { escapeIdPart } from 'surrealdb';
// String IDs
console.log(escapeIdPart('john')); // 'john' or escaped equivalent
// Numeric IDs
console.log(escapeIdPart(123)); // '123'
console.log(escapeIdPart(42n)); // '42'
// UUID values
console.log(escapeIdPart(new Uuid('...'))); escapeRangeBound(bound)
Escape a range bound value for use in SurrealQL range expressions.
function escapeRangeBound<T>(bound: Bound<T>): stringParameters
Parameter | Type | Description |
|---|---|---|
bound | Bound<T> | The range bound to escape. |
Returns
string - Escaped range bound representation
Complete examples
Dynamic table names
import { escapeIdent } from 'surrealdb';
async function selectFromTable(tableName: string) {
// Validate and escape table name
const safeTable = escapeIdent(tableName);
// Use in query (still prefer Table class)
const query = `SELECT * FROM ${safeTable}`;
const [results] = await db.query(query).collect();
return results;
}
await selectFromTable('user-sessions'); // SafeDynamic field selection
import { escapeIdent } from 'surrealdb';
async function selectFields(table: string, fields: string[]) {
const escapedFields = fields.map(escapeIdent).join(', ');
const escapedTable = escapeIdent(table);
const query = `SELECT ${escapedFields} FROM ${escapedTable}`;
const [results] = await db.query(query).collect();
return results;
}
await selectFields('users', ['first-name', 'last-name', 'email']);Using surql instead (recommended)
// Prefer surql for safe parameterisation
const filters = { status: 'active', age: 18 };
const query = surql`
SELECT * FROM users
WHERE status = ${filters.status}
AND age = ${filters.age}
`;When to use
✅ Use escape functions when:
Constructing queries with user-provided table/field names
Working with identifiers that have special characters
Building dynamic schema definitions
Interfacing with external query builders
❌ Prefer other solutions:
For values: Use
surqlorBoundQueryFor tables: Use
TableclassFor record IDs: Use
RecordIdclassFor conditions: Use
expr
Best practices
1. Prefer type-safe alternatives
// Good: Type-safe
const table = new Table('users');
const users = await db.select(table);
// Avoid: Manual escaping
const escaped = escapeIdent('users');
const users = await db.query(`SELECT * FROM ${escaped}`).collect();2. Validate before escaping
// Good: Validate first
function safeQuery(tableName: string) {
if (!isValidTable(tableName)) {
throw new Error('Invalid table name');
}
const escaped = escapeIdent(tableName);
return `SELECT * FROM ${escaped}`;
}
// Avoid: Blind escaping
function unsafeQuery(tableName: string) {
return `SELECT * FROM ${escapeIdent(tableName)}`;
}3. Use surql for complex queries
// Good: Automatic parameterisation
const query = surql`SELECT * FROM users WHERE name = ${name}`;
// Avoid: Manual string construction
const query = `SELECT * FROM users WHERE name = '${name}'`;Security considerations
Escaping functions are NOT a complete defense against SQL injection. Always prefer parameterised queries using surql or BoundQuery.
// Secure: Parameterised
const query = surql`SELECT * FROM users WHERE name = ${userInput}`;
// Insecure: No escaping
const query = `SELECT * FROM users WHERE name = '${userInput}'`;See also
surql - Recommended for parameterised queries
BoundQuery - Parameterised query class
Table - Type-safe table references
RecordId - Type-safe record identifiers