Queries
Construction
Section titled “Construction”jsorm uses a structured JSON query shape instead of chain builders.
Select
Section titled “Select”const rows = await db.get(User, { select: { id: true, name: true, role: { name: true }, _count: true, }, where: { AND: [ { active: true }, { role: { name: { eq: 'admin' } } }, ], }, orderBy: [{ createdAt: 'desc' }],});When pagination is omitted, get() applies a default LIMIT 150 to prevent accidental full-table fetches. Override with JSORM_LIMIT_DEFAULT.
Scalar where operators
Section titled “Scalar where operators”| Operator | Behavior |
|---|---|
{ eq: value } | Equal |
{ ne: value } | Not equal |
{ gt: value } | Greater than |
{ gte: value } | Greater than or equal |
{ lt: value } | Less than |
{ lte: value } | Less than or equal |
{ in: [...] } | Value in list |
{ contains: string } | LIKE %value% |
{ startsWith: string } | LIKE value% |
{ endsWith: string } | LIKE %value |
Logical operators
Section titled “Logical operators”const rows = await db.get(User, { select: { id: true, name: true }, where: { OR: [ { email: { contains: '@corp.com' } }, { role: { name: { eq: 'admin' } } }, ], },});Cursor pagination
Section titled “Cursor pagination”const page = await db.get(User, { select: { id: true, name: true }, orderBy: [{ id: 'asc' }], cursor: { after: '...opaque-base64url-token...', take: 25, },});// page.pageInfo: { hasNextPage, hasPreviousPage, startCursor, endCursor }Cursor rules:
cursormode requiresorderBy- jsorm auto-appends a primary-key tie-breaker when needed
cursor.takeis clamped byJSORM_CURSOR_HARD_MAX_LIMIT(default1000)
Insert / update / delete
Section titled “Insert / update / delete”await db.insert(User, { name: 'Alice', createdAt: new Date(), role: { connect: 1 },});
await db.update(User, { data: { active: false }, where: { id: { eq: 10 } },});
await db.delete(User, { where: { id: { eq: 10 } },});Relation mutations
Section titled “Relation mutations”await db.insert(User, { name: 'Bob', createdAt: new Date(), roles: [1, 2],});
await db.update(User, { data: { roles: { connect: [3], disconnect: [1] }, }, where: { id: { eq: 5 } },});Raw SQL
Section titled “Raw SQL”Use the documented escape hatch only:
const rows = await db.raw.execute( 'SELECT id, name FROM users WHERE active = $1 AND created_at > $2', [true, new Date('2024-01-01')],);
const compiled = await db.raw.compile( 'SELECT id, name FROM users WHERE active = $1', [true],);Best practices
Section titled “Best practices”- Keep
whereexplicit on all write operations. - Prefer nested relation filters over handwritten join SQL.
- Use
orderBywith pagination for stable list endpoints. - Use
cursorpagination for large or infinite-scroll datasets. - Reserve
db.raw.*for queries the JSON DSL genuinely cannot express cleanly.