DeesseJS Collections

Queries

Understanding CRUD operations and basic queries

Queries

Collections provides a powerful query API for performing CRUD operations with full type safety. All operations are automatically typed based on your collection definitions.

Overview

Every collection exposes these operations:

Prop

Type

Read Operations

findMany

Retrieve multiple records with optional filtering and pagination:

// Get all users
const users = await collections.users.findMany()

// With filtering
const activeUsers = await collections.users.findMany({
  where: {
    status: { equals: 'active' }
  }
})

// With pagination
const users = await collections.users.findMany({
  limit: 10,
  offset: 20
})

// With sorting
const users = await collections.users.findMany({
  orderBy: {
    createdAt: 'desc'
  }
})

// Combined
const users = await collections.users.findMany({
  where: {
    status: { equals: 'active' }
  },
  orderBy: {
    createdAt: 'desc'
  },
  limit: 10,
  offset: 0
})

findUnique

Retrieve a single record by its unique identifier:

const user = await collections.users.findUnique({
  where: { id: 1 }
})

// With error handling
try {
  const user = await collections.users.findUnique({
    where: { id: 1 }
  })
  console.log(user.name)
} catch (error) {
  if (error.code === 'NOT_FOUND') {
    console.log('User not found')
  }
}

findFirst

Retrieve the first record matching criteria:

// Get first active user
const user = await collections.users.findFirst({
  where: {
    status: { equals: 'active' }
  },
  orderBy: {
    createdAt: 'asc'
  }
})

// Get first user with specific email
const user = await collections.users.findFirst({
  where: {
    email: { equals: 'user@example.com' }
  }
})

Create Operations

create

Create a single new record:

const user = await collections.users.create({
  data: {
    name: 'John Doe',
    email: 'john@example.com',
    status: 'active'
  }
})

console.log(user.id) // Auto-generated ID
console.log(user.createdAt) // Auto-generated timestamp

createMany

Create multiple records in a single operation:

const users = await collections.users.createMany({
  data: [
    {
      name: 'John Doe',
      email: 'john@example.com'
    },
    {
      name: 'Jane Smith',
      email: 'jane@example.com'
    },
    {
      name: 'Bob Johnson',
      email: 'bob@example.com'
    }
  ]
})

console.log(users.count) // Number of created records

Update Operations

update

Update a single record:

const user = await collections.users.update({
  where: { id: 1 },
  data: {
    name: 'Jane Doe',
    status: 'inactive'
  }
})

updateMany

Update multiple records matching criteria:

const result = await collections.users.updateMany({
  where: {
    status: { equals: 'inactive' }
  },
  data: {
    status: 'archived'
  }
})

console.log(result.count) // Number of updated records

Delete Operations

delete

Delete a single record:

await collections.users.delete({
  where: { id: 1 }
})

deleteMany

Delete multiple records matching criteria:

const result = await collections.users.deleteMany({
  where: {
    status: { equals: 'archived' }
  }
})

console.log(result.count) // Number of deleted records

Count Operations

count

Count records matching criteria:

// Count all users
const total = await collections.users.count()

// Count active users
const active = await collections.users.count({
  where: {
    status: { equals: 'active' }
  }
})

console.log(`Total: ${total}, Active: ${active}`)

Type Safety

All operations are fully typed based on your field definitions:

// Type is inferred from field definitions
const user = await collections.users.create({
  data: {
    name: 'John Doe',      // ✅ string - correct
    email: 'john@example.com', // ✅ string - correct
    age: 25,               // ✅ number - correct
    status: 'active'       // ✅ 'active' | 'inactive' - enum
  }
})

// TypeScript will catch errors
const user = await collections.users.create({
  data: {
    name: 123,             // ❌ Error: number not assignable to string
    email: 'invalid',      // ❌ Error: invalid email format (validation)
    age: '25',             // ❌ Error: string not assignable to number
    status: 'unknown'      // ❌ Error: not in enum
  }
})

Query Options

All query operations accept these options:

Prop

Type

Return Types

Operations return typed results:

// findMany returns array
const users: User[] = await collections.users.findMany()

// findUnique returns single record or null
const user: User | null = await collections.users.findUnique({
  where: { id: 1 }
})

// create returns created record
const newUser: User = await collections.users.create({
  data: { name: 'John' }
})

// count returns number
const total: number = await collections.users.count()

Error Handling

Operations throw errors for invalid data or database issues:

try {
  const user = await collections.users.create({
    data: {
      name: 'John',
      email: 'john@example.com'
    }
  })
} catch (error) {
  if (error.code === 'VALIDATION_ERROR') {
    console.log('Validation failed:', error.messages)
  } else if (error.code === 'UNIQUE_CONSTRAINT') {
    console.log('Email already exists')
  } else {
    console.log('Database error:', error.message)
  }
}

See Error Handling for complete error reference.

Examples

User Registration

const registerUser = async (email: string, password: string) => {
  // Check if user exists
  const existing = await collections.users.findFirst({
    where: { email: { equals: email } }
  })

  if (existing) {
    throw new Error('User already exists')
  }

  // Create user
  const user = await collections.users.create({
    data: {
      email,
      password: await hash(password),
      status: 'active'
    }
  })

  return user
}

Update User Profile

const updateProfile = async (userId: number, updates: Partial<User>) => {
  const user = await collections.users.update({
    where: { id: userId },
    data: updates
  })

  return user
}

Soft Delete

const softDelete = async (userId: number) => {
  await collections.users.update({
    where: { id: userId },
    data: {
      deletedAt: new Date(),
      status: 'deleted'
    }
  })
}

Next Steps

On this page