# Source: https://remult.dev/llms-small.txt

# Getting Started - Introduction

<script setup>
  import Icon from '../components/Icon.vue'
</script>

# Introduction

**Remult** is a fullstack CRUD framework that uses your TypeScript model types to provide:

- Secure REST API (highly configurable)
- Type-safe frontend API client
- Type-safe backend query builder

#### Use the same model classes for both frontend and backend code

With Remult it is simple to keep your code [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself) and increase development speed and maintainability by defining a single TypeScript model class (for each domain object) and sharing it between your frontend and backend code.

As Remult is "aware" of the runtime context (frontend or backend), data validations and entity lifecycle hooks can be written in layer-agnostic TypeScript which will run, as needed, on either the frontend, the backend, or both.

## Choose Your Remult Learning Path

Explore the flexibility of Remult through different learning paths tailored to match your style and project needs.

### `Option A`: Start with the Interactive Online Tutorial

If you're new to Remult or prefer a guided, hands-on approach, we recommend starting with our [interactive online tutorial](https://learn.remult.dev). This tutorial will walk you through building a full-stack application step by step, providing immediate feedback and insights as you learn.

### `Option B`: Create a new Project

[`npm init remult@latest`](./creating-a-project.md)

### `Option C`: Follow a Step-by-step Tutorial

<br />
<br />

<div style="display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 5rem">
	<Icon tech="react" sizeIco:=150 link="/tutorials/react" techName="React" />
	<Icon tech="angular" sizeIco:=150 link="/tutorials/angular" techName="Angular" />
	<Icon tech="vue" sizeIco:=150 link="/tutorials/vue" techName="Vue" />
	<Icon tech="svelte" sizeIco:=150 link="/tutorials/sveltekit" techName="SvelteKit" />
	<Icon tech="nextjs" sizeIco:=150 link="/tutorials/react-next" techName="Next.js" />
	<Icon tech="solid" sizeIco:=150 link="/tutorials/solid-start" techName="SolidStart" />
</div>

### `Option D`: Quickstart

Use this [Quickstart](./quickstart.md) guide to quickly setup and try out Remult or add Remult to an existing app.

### `Option E`: Browse Example Apps

[Example Apps](./example-apps.md)

### `Option F`: Video Tutorials

Check out these official [Remult video tutorials](https://youtube.com/playlist?list=PLlcnBwFkuOn166nXXxxfL9Hee-1GWlDSm&si=TDlwIFDLi4VMi-as).



# Getting Started - Creating a project

<script setup>
  import Example from '../components/Example.vue'
</script>

# Creating a Remult Project

_The easiest way to start building a Remult app_

```bash
npm init remult@latest
```

Yes, that's it!
::: tip
Let us know how you liked the process! [@remultjs](https://twitter.com/RemultJs)
:::

## Demo

![npm init remult](/npm_init_remult.gif)

## What you get ?

<!-- Remult offers a streamlined project creation process that caters to over `180` different project flavors, ensuring you'll find the perfect setup for your needs. With just a few simple questions, you will get a fully functional Remult project up and running in no time.

Here's what you can expect: -->

### 1. **Tailored Setup**

Answer a few questions about your preferred tech stack and project requirements.

`Project name`: The name of your project _(it will create a folder with this name)_

`Choose your Framework` <Example :oneline=true :react=true :angular=true :vue=true :nextjs=true :svelte=true :nuxt=true />

`Choose your Web Server` _(if needed)_ <Example :oneline=true :express=true :fastify=true />

`Choose your Database` <Example :oneline=true :json=true :postgres=true :mysql=true :sqlite=true :mongodb=true :mssql=true />

`Authentication`: Do you want to add `auth.js` to your project directly ? including a complete implementation for `credentials` and `github` providers

`Add CRUD demo`: A comprehensive example of how to use an entity. It will show you how to create, read, update and delete data.

`Admin UI`: Will then be available at `/api/admin`

### 2. **Instant Configuration**

Based on your answers, Remult will configure the project with the best-suited options. With all combinations of frameworks, servers, databases and authentication, we manage more than `180 different project flavors`! We are missing yours? Let us know !

### 3. **Feature-Rich Demo**

Once you run your project, you'll be greeted with a comprehensive dashboard that showcases all of Remult's powerful features. It will look like this:

![Remult Dashboard](/create-remult.png)

Each tile is a fully functional example of a feature that you selected.

### 4. **Easy Eject**

Simply remove the demo folder to eject the demo components.



# Getting Started - Quickstart

# Quickstart

Jumpstart your development with this Quickstart guide. Learn to seamlessly integrate Remult in various stacks, from installation to defining entities for efficient data querying and manipulation.

### Experience Remult with an Interactive Tutorial

For a guided, hands-on experience, [try our interactive online tutorial](https://learn.remult.dev/). It's the fastest way to get up and running with Remult and understand its powerful features.

## Installation

The _remult_ package is all you need for both frontend and backend code. If you're using one `package.json` for both frontend and backend (or a meta-framework) - **install Remult once** in the project's root folder. If you're using multiple `package.json` files (monorepo) - **install Remult in both server and client folders**.

::: code-group

```sh [npm]
npm install remult
```

```sh [yarn]
yarn add remult
```

```sh [pnpm]
pnpm add remult
```

```sh [bun]
bun add remult
```

:::

## Server-side Initialization

Remult is initialized on the server-side as a request handling middleware, with **a single line of code**. Here is the code for setting up the Remult middleware:

::: code-group

```ts [Express]
import express from 'express'
import { remultApi } from 'remult/remult-express'

const app = express()

app.use(remultApi({})) // [!code highlight]

app.listen(3000)
```

<!-- prettier-ignore-start -->
```ts [Fastify]
import fastify from 'fastify'
import { remultApi } from 'remult/remult-fastify'

(async () => {
  const server = fastify()

  await server.register(remultApi({})) // [!code highlight]

  server.listen({ port: 3000 })
})()
```
<!-- prettier-ignore-end -->

```ts [Next.js]
// src/app/api/[...remult]/route.ts

import { remultApi } from 'remult/remult-next'

export const api = remultApi({}) // [!code highlight]

export const { GET, POST, PUT, DELETE } = api
```

```ts [Sveltekit]
// src/routes/api/[...remult]/+server.ts

import { remultApi } from 'remult/remult-sveltekit'

export const _api = remultApi({}) // [!code highlight]

export const { GET, POST, PUT, DELETE } = _api
```

```ts [nuxt.js]
// server/api/[...remult].ts

import { remultApi } from 'remult/remult-nuxt'

export const api = remultApi({})

export default defineEventHandler(api)

// enable experimental decorators
// Add to nuxt.config.ts
  nitro: {
    esbuild: {
      options: {
        tsconfigRaw: {
          compilerOptions: {
            experimentalDecorators: true,
          },
        },
      },
    },
  },
  vite: {
    esbuild: {
      tsconfigRaw: {
        compilerOptions: {
          experimentalDecorators: true,
        },
      },
    },
  },


```

<!-- prettier-ignore-start -->
```ts [Hapi]
import { type Plugin, server } from '@hapi/hapi'
import { remultApi } from 'remult/remult-hapi'

(async () => {
  const hapi = server({ port: 3000 })

  await hapi.register(remultApi({})) // [!code highlight]

  hapi.start()
})()
```
<!-- prettier-ignore-end -->

```ts [Hono]
import { Hono } from 'hono'
import { serve } from '@hono/node-server'
import { remultApi } from 'remult/remult-hono'

const app = new Hono()

const api = remultApi({}) // [!code highlight]
app.route('', api) // [!code highlight]

serve(app)
```

```ts [Nest]
// src/main.ts

import { remultApi } from 'remult/remult-express'

async function bootstrap() {
  const app = await NestFactory.create(AppModule)

  app.use(remultApi({})) // [!code highlight]

  await app.listen(3000)
}
bootstrap()
```

```ts{9-17} [Koa]
import * as koa from 'koa'
import * as bodyParser from 'koa-bodyparser'
import { createRemultServer } from 'remult/server'

const app = new koa()

app.use(bodyParser())

const api = createRemultServer({})

app.use(async (ctx, next) => {
  const r = await api.handle(ctx.request)
  if (r) {
    ctx.response.body = r.data
    ctx.response.status = r.statusCode
  } else return await next()
})

app.listen(3000, () => {})
```

:::

## Connecting a Database

Use the `dataProvider` property of Remult's server middleware to set up a database connection for Remult.

::: tip Recommended - Use default local JSON files and connect a database later
If the `dataProvider` property is not set, Remult stores data as JSON files under the `./db` folder.
:::

Here are examples of connecting to some commonly used back-end databases:

::: tabs

== Postgres
Install node-postgres:

```sh
npm i pg
```

Set the `dataProvider` property:

```ts{3,7,11-15}
import express from "express"
import { remultApi } from "remult/remult-express"
import { createPostgresDataProvider } from "remult/postgres"

const app = express()

const connectionString = "postgres://user:password@host:5432/database"

app.use(
  remultApi({
    dataProvider:
      createPostgresDataProvider({
        connectionString, // default: process.env["DATABASE_URL"]
        // configuration: {} // optional = a `pg.PoolConfig` object or "heroku"
      })
  })
)
```

Or use your existing postgres connection

```ts
import { Pool } from 'pg'
import { SqlDatabase } from 'remult'
import { PostgresDataProvider } from 'remult/postgres'
import { remultApi } from 'remult/remult-express'
const pg = new Pool({
  connectionString: '....',
})
const app = express()
app.use(
  remultApi({
    dataProvider: new SqlDatabase(new PostgresDataProvider(pg)),
  }),
)
```

== MySQL

Install knex and mysql2:

```sh
npm i knex mysql2
```

Set the `dataProvider` property:

```ts{3,9-18}
import express from "express"
import { remultApi } from "remult/remult-express"
import { createKnexDataProvider } from "remult/remult-knex"

const app = express()

app.use(
  remultApi({
    dataProvider: createKnexDataProvider({
      // Knex client configuration for MySQL
      client: "mysql2",
      connection: {
        user: "your_database_user",
        password: "your_database_password",
        host: "127.0.0.1",
        database: "test"
      }
    })
  })
)
```

Or use your existing knex provider

```ts
import express from 'express'
import { KnexDataProvider } from 'remult/remult-knex'
import { remultApi } from 'remult/remult-express'
import knex from 'knex'

const knexDb = knex({
  client: '...',
  connection: '...',
})

const app = express()

app.use(
  remultApi({
    dataProvider: new KnexDataProvider(knexDb), // [!code highlight]
  }),
)
```

== MongoDB

Install mongodb:

```sh
npm i mongodb
```

Set the `dataProvider` property:

```ts{3-4,10-14}
import express from "express"
import { remultApi } from "remult/remult-express"
import { MongoClient } from "mongodb"
import { MongoDataProvider } from "remult/remult-mongo"

const app = express()

app.use(
  remultApi({
    dataProvider: async () => {
      const client = new MongoClient("mongodb://localhost:27017/local")
      await client.connect()
      return new MongoDataProvider(client.db("test"), client)
    }
  })
)
```

== SQLite

There are several sqlite providers supported

### Better-sqlite3

Install better-sqlite3:

```sh
npm i better-sqlite3
```

Set the `dataProvider` property:

```ts
import express from 'express'
import { remultApi } from 'remult/remult-express'
import { SqlDatabase } from 'remult' // [!code highlight]
import Database from 'better-sqlite3' // [!code highlight]
import { BetterSqlite3DataProvider } from 'remult/remult-better-sqlite3' // [!code highlight]

const app = express()

app.use(
  remultApi({
    dataProvider: new SqlDatabase( // [!code highlight]
      new BetterSqlite3DataProvider(new Database('./mydb.sqlite')), // [!code highlight]
    ), // [!code highlight]
  }),
)
```

### sqlite3

This version of sqlite3 works even on stackblitz

Install sqlite3:

```sh
npm i sqlite3
```

Set the `dataProvider` property:

```ts
import express from 'express'
import { remultApi } from 'remult/remult-express'
import { SqlDatabase } from 'remult' // [!code highlight]
import sqlite3 from 'sqlite3' // [!code highlight]
import { Sqlite3DataProvider } from 'remult/remult-sqlite3' // [!code highlight]

const app = express()

app.use(
  remultApi({
    dataProvider: new SqlDatabase( // [!code highlight]
      new Sqlite3DataProvider(new sqlite3.Database('./mydb.sqlite')), // [!code highlight]
    ), // [!code highlight]
  }),
)
```

### bun:sqlite

Set the `dataProvider` property:

```ts
import express from 'express'
import { remultApi } from 'remult/remult-express'
import { SqlDatabase } from 'remult' // [!code highlight]
import { Database } from 'bun:sqlite' // [!code highlight]
import { BunSqliteDataProvider } from 'remult/remult-bun-sqlite' // [!code highlight]

const app = express()

app.use(
  remultApi({
    dataProvider: new SqlDatabase( // [!code highlight]
      new BunSqliteDataProvider(new Database('./mydb.sqlite')), // [!code highlight]
    ), // [!code highlight]
  }),
)
```

### sql.js

Install sqlite3:

```sh
npm i sql.js
```

Set the `dataProvider` property:

```ts
import express from 'express'
import { remultApi } from 'remult/remult-express'
import { SqlDatabase } from 'remult' // [!code highlight]
import initSqlJs from 'sql.js' // [!code highlight]
import { SqlJsDataProvider } from 'remult/remult-sql-js' // [!code highlight]

const app = express()

app.use(
  remultApi({
    dataProvider: new SqlDatabase( // [!code highlight]
      new SqlJsDataProvider(initSqlJs().then((x) => new x.Database())), // [!code highlight]
    ), // [!code highlight]
  }),
)
```

### Turso

Install turso:

```sh
npm install @libsql/client
```

Set the `dataProvider` property:

<!-- prettier-ignore-start -->
```ts
import express from 'express'
import { remultApi } from 'remult/remult-express'
import { SqlDatabase } from 'remult' // [!code highlight]
import { createClient } from '@libsql/client' // [!code highlight]
import { TursoDataProvider } from 'remult/remult-turso' // [!code highlight]

const app = express()

app.use(
  remultApi({
    dataProvider: new SqlDatabase( // [!code highlight]
      new TursoDataProvider( // [!code highlight]
        createClient({ // [!code highlight]
          url: process.env.TURSO_DATABASE_URL, // [!code highlight]
          authToken: process.env.TURSO_AUTH_TOKEN, // [!code highlight]
        }), // [!code highlight]
      ), // [!code highlight]
    ), // [!code highlight]
  }),
)
```
<!-- prettier-ignore-end -->

== Microsoft SQL Server

Install knex and tedious:

```sh
npm i knex tedious
```

Set the `dataProvider` property:

```ts{5,11-25}
// index.ts

import express from "express"
import { remultApi } from "remult/remult-express"
import { createKnexDataProvider } from "remult/remult-knex"

const app = express()

app.use(
  remultApi({
    dataProvider: createKnexDataProvider({
      // Knex client configuration for MSSQL
      client: "mssql",
      connection: {
        server: "127.0.0.1",
        database: "test",
        user: "your_database_user",
        password: "your_database_password",
        options: {
          enableArithAbort: true,
          encrypt: false,
          instanceName: `sqlexpress`
        }
      }
    })
  })
)
```

Or use your existing knex provider

```ts
import express from 'express'
import { KnexDataProvider } from 'remult/remult-knex'
import { remultApi } from 'remult/remult-express'
import knex from 'knex'

const knexDb = knex({
  client: '...',
  connection: '...',
})

const app = express()

app.use(
  remultApi({
    dataProvider: new KnexDataProvider(knexDb), // [!code highlight]
  }),
)
```

== DuckDB
Install DuckDB:

```sh
npm i @duckdb/node-api
```

Set the `dataProvider` property:

```ts
import express from 'express'
import { remultApi } from 'remult/remult-express'
import { SqlDatabase } from 'remult' // [!code highlight]
import { DuckDBInstance } from '@duckdb/node-api' // [!code highlight]
import { DuckDBDataProvider } from 'remult/remult-duckdb' // [!code highlight]

const app = express()

app.use(
  remultApi({
    dataProvider: new SqlDatabase( // [!code highlight]
      new DuckDBDataProvider(
        (await DuckDBInstance.create(':memory:')).connect(),
      ), // [!code highlight]
    ), // [!code highlight]
  }),
)
```

== Oracle

Install knex and oracledb:

```sh
npm i knex oracledb
```

Set the `dataProvider` property:

```ts{5,11-19}
// index.ts

import express from "express"
import { remultApi } from "remult/remult-express"
import { createKnexDataProvider } from "remult/remult-knex"

const app = express()

app.use(
  remultApi({
    dataProvider: createKnexDataProvider({
      // Knex client configuration for Oracle
      client: "oracledb",
      connection: {
        user: "your_database_user",
        password: "your_database_password",
        connectString: "SERVER"
      }
    })
  })
)
```

Or use your existing knex provider

```ts
import express from 'express'
import { KnexDataProvider } from 'remult/remult-knex'
import { remultApi } from 'remult/remult-express'
import knex from 'knex'

const knexDb = knex({
  client: '...',
  connection: '...',
})

const app = express()

app.use(
  remultApi({
    dataProvider: new KnexDataProvider(knexDb), // [!code highlight]
  }),
)
```

== JSON Files

Set the `dataProvider` property:

```ts{5-6,12-14}
// index.ts

import express from "express"
import { remultApi } from "remult/remult-express"
import { JsonDataProvider } from "remult"
import { JsonEntityFileStorage } from "remult/server"

const app = express()

app.use(
  remultApi({
    dataProvider: async () =>
      new JsonDataProvider(new JsonEntityFileStorage("./db"))
  })
)
```

:::

## Integrate Auth

**Remult is completely unopinionated when it comes to user authentication.** You are free to use any kind of authentication mechanism, and only required to provide Remult with a [`getUser`](./ref_remultserveroptions.md#getuser) function that extracts a user object (which implements the minimal Remult `UserInfo` interface) from a request.

Here are examples of integrating some commonly used auth providers:

::: code-group

```ts [express-session]
import express from 'express'
import session from 'express-session'
import { remultApi } from 'remult/remult-express'

const app = express()

app.use(
  session({
    /* ... */
  }),
)

app.post('/api/signIn', (req, res) => {
  req.session!['user'] = { id: 1, name: 'admin', roles: ['admin'] }
})

app.use(
  remultApi({
    getUser: (req) => req.session!['user'], // [!code highlight]
  }),
)
```

```ts{8-13} [next-auth]
// src/app/api/[...remult]/route.ts

import { remultApi } from 'remult/remult-next'
import { getServerSession } from 'next-auth'
import { authOptions } from '../auth/[...nextauth]/route'

export const api = remultApi({
  getUser: async () => {
    const user = (await getServerSession(authOptions))?.user
    return user?.email && user?.name
      ? { id: user?.email, name: user?.name }
      : undefined
  },
})

export const { POST, PUT, DELETE, GET, withRemult } = api
```

:::

## Defining and Serving an Entity

Remult entity classes are shared between frontend and backend code.

```ts
// shared/product.ts

import { Entity, Fields } from 'remult'

@Entity('products', {
  allowApiCrud: true,
  allowApiDelete: 'admin',
})
export class Product {
  @Fields.id()
  id!: string

  @Fields.string()
  name = ''

  @Fields.number()
  unitPrice = 0
}
```

Alternatively, [generate entities](./entities-codegen-from-db-schema.md) from an existing Postgres database.

### Serve Entity CRUD API

All Remult server middleware options contain an [`entities`](./ref_remultserveroptions.md#entities) array. Use it to register your Entity.

```ts
// backend/index.ts

app.use(
  remultApi({
    entities: [Product], // [!code highlight]
  }),
)
```

## Using your Entity on the Client

To start querying and mutating data from the client-side using Remult, use the [`repo`](./ref_remult.md#repo) function to create a [`Repository`](./ref_repository.md) object for your entity class. This approach simplifies data operations, allowing you to interact with your backend with the assurance of type safety.

```ts
// frontend/code.ts

import { repo } from 'remult'
import { Product } from '../shared/product'

const productsRepo = repo(Product)

async function playWithRemult() {
  // add a new product to the backend database
  await productsRepo.insert({ name: 'Tofu', unitPrice: 5 })

  // fetch products from backend database
  const products = await productsRepo.find({
    where: { unitPrice: { '>=': 5 } },
    orderBy: { name: 'asc' },
    limit: 10,
  })
  console.log(products)

  // update product data
  const tofu = products.filter((p) => p.name === 'Tofu')
  await productsRepo.save({ ...tofu, unitPrice: tofu.unitPrice + 5 })

  // delete product
  await productsRepo.delete(tofu)
}

playWithRemult()
```

## Client-side Customization

::: tip Recommended Defaults
By default, remult uses the browser's [fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API), and makes data API calls using the base URL `/api` (same-origin).
:::

### Changing the default API base URL

To use a different origin or base URL for API calls, set the remult object's `apiClient.url` property.

```ts
remult.apiClient.url = 'http://localhost:3002/api'
```

### Using an alternative HTTP client

Set the `remult` object's `apiClient.httpClient` property to customize the HTTP client used by Remult:

::: code-group

```ts [Axios instead of Fetch]
import axios from 'axios'
import { remult } from 'remult'

remult.apiClient.httpClient = axios
```

```ts [Angular HttpClient instead of Fetch]
//...
import { HttpClientModule, HttpClient } from '@angular/common/http'
import { remult } from 'remult'

@NgModule({
  //...
  imports: [
    //...
    HttpClientModule,
  ],
})
export class AppModule {
  constructor(http: HttpClient) {
    remult.apiClient.httpClient = http
  }
}
```

:::



# Getting Started - Example Apps

<script setup>
  import Example from '../components/Example.vue'
  import Icon from '../components/Icon.vue'
</script>

# Example Apps

We have already a _ton_ of examples! Pick and choose the one that fits your needs 😊

## Todo MVC

<Example
	imgSrc="/example-apps/todoMVC.png"
 	:react=true :vite=true :express=true 
	github="https://github.com/remult/TodoMVC-example"
	codesandbox="https://codesandbox.io/s/github/remult/TodoMVC-example?file=/src/frontend/App.tsx"
/>

## CRM Demo

A fully featured CRM! Make sure to check out the link: <b>Dev / Admin</b> on top right!
<Example
	imgSrc="/example-apps/CRM.png"
 	:react=true :vite=true :express=true :postgres=true :mui=true
	live="https://crm-demo.up.railway.app/"
	github="https://github.com/remult/crm-demo"
/>

## Shadcn React Table

Using remult with server side sorting, filtering, paging & CRUD
<Example
	imgSrc="/example-apps/shadcn.png"
 	:react=true :vite=true :express=true :postgres=true :shadcn=true
	live="https://table.up.railway.app/"
	github="https://www.github.com/remult/remult/tree/main/examples/shadcn-react-table"
	stackblitz="https://stackblitz.com/github/remult/remult/tree/main/examples/shadcn-react-table"
/>

## TanStack React Table

Example of using remult with react table - most basic design, with server side sorting, paging & filtering
<Example
	title='TanStack React Table'
	imgSrc="/example-apps/tanStack.png"
 	:react=true :vite=true :tanstack=true
	github="https://www.github.com/remult/remult/tree/main/examples/tanstack-react-table"
	stackblitz="https://stackblitz.com/github/remult/remult/tree/main/examples/tanstack-react-table"
/>

## 🚀 Ready to play

An environment to reproduce issues using stackblitz, with optional sqlite database
<Example
	imgSrc="/example-apps/ready-to-play.png"
 	:react=true :vite=true :sqlite=true :express=true
	github="https://www.github.com/noam-honig/ready-to-play"
	stackblitz="https://stackblitz.com/github/noam-honig/ready-to-play"
/>

## Group by Example

And example of the usage of groupBy
<Example
	imgSrc="/example-apps/groupby.png"
 	:react=true :vite=true :express=true
	github="https://github.com/remult/remult/tree/main/examples/groupBy"
	stackblitz="https://stackblitz.com/github/remult/remult/tree/main/examples/groupBy?file=src%2Ffrontend%2Fpage.tsx"
/>

## Todo for most frameworks

- [React & Express](https://github.com/remult/remult/tree/main/examples/react-todo)
- [React & bun & Hono](https://github.com/remult/remult/tree/main/examples/bun-react-hono-monorepo-todo)
- [Next.js (App Router)](https://github.com/remult/remult/tree/main/examples/nextjs-app-router-todo)
- [Next.js (Pages)](https://github.com/remult/remult/tree/main/examples/nextjs-todo)
- [Angular & Express](https://github.com/remult/remult/tree/main/examples/angular-todo)
- [Angular & Fastify](https://github.com/remult/remult/tree/main/examples/angular-todo-fastify)
- [Vue](https://github.com/remult/remult/tree/main/examples/vue-todo)
- [Nuxt3](https://github.com/remult/remult/tree/main/examples/nuxt-todo)
- [SvelteKit](https://github.com/remult/remult/tree/main/examples/sveltekit-todo)
- [SolidStart](https://github.com/remult/remult/tree/main/examples/solid-start-todo)

## Other example

- [Using BackendMethod queued option](https://stackblitz.com/edit/github-vwfkxu?file=src%2FApp.tsx)
- [Using SubscriptionChannel to update the frontend](https://stackblitz.com/edit/github-3nmwrp?file=src%2FApp.tsx)
- [Next.js Auth with remult user table](https://github.com/noam-honig/nextjs-auth-remult-user-table)
- [Unit tests for api](https://stackblitz.com/edit/api-test-example?file=test.spec.ts,model.ts)
- [Extending field options with open api specific properties](https://github.com/noam-honig/adding-open-api-options/)



# Entities

<script setup>
  import Remultor from '../.vitepress/components/Remultor.vue'
</script>

# Entities

Entities are **THE** key concept of Remult - your **Single Source of Truth (SSoT)** for data structure, api, validation, permissions, and more! In other languages, they can be called `schema` or `model`.

---

# 🧙‍♂️ Remultor

Real-time Remult entity builder. Try it out and copy the code to your project!

<Remultor />



# Entities - Fields

# Field Types

## Common field types

There are also several built in Field decorators for common use case:

### @Fields.string

A field of type string

```ts
@Fields.string()
title = '';
```

### @Fields.number

Just like TypeScript, by default any number is a decimal (or float).

```ts
@Fields.number()
price = 1.5
```

### @Fields.integer

For cases where you don't want to have decimal values, you can use the `@Fields.integer` decorator

```ts
@Fields.integer()
quantity = 0;
```

### @Fields.boolean

```ts
@Fields.boolean()
completed = false
```

### @Fields.date

```ts
@Fields.date()
statusDate = new Date()
```

### @Fields.dateOnly

Just like TypeScript, by default any `Date` field includes the time as well.
For cases where you only want a date, and don't want to meddle with time and time zone issues, use the `@Fields.dateOnly`

```ts
@Fields.dateOnly()
birthDate?:Date;
```

### @Fields.createdAt

Automatically set on the backend on insert, and can't be set through the API

```ts
@Fields.createdAt()
createdAt = new Date()
```

### @Fields.updatedAt

Automatically set on the backend on update, and can't be set through the API

```ts
@Fields.updatedAt()
updatedAt = new Date()
```

## JSON Field

You can store JSON data and arrays in fields.

```ts
@Fields.json()
tags: string[] = []
```

## Auto Generated Id Field Types

### @Fields.id

This id value is determined on the backend on insert, and can't be updated through the API.

```ts
@Fields.id()
id:string
```

By default it uses `crypto.randomUUID` to generate the id.

You can change the algorithm used to generate the id by setting the `Fields.defaultIdFactory`
to a different function like:

```ts
import { createId } from '@paralleldrive/cuid2'
Fields.defaultIdOptions = { idFactory: () => createId() }
```

You can also pass an id factory as an option to the `@Fields.id` to have a different value locally.

```ts
import { createId } from '@paralleldrive/cuid2'
// import { v4 as uuid } from 'uuid'
// import { nanoid } from 'nanoid'
// import { ulid } from 'ulid'

class MyEntity {
  @Fields.id({
    idFactory: () => createId(),
    // idFactory: () => uuid()
    // idFactory: () => nanoid()
    // idFactory: () => ulid()
  })
  id: string = ''
}
```

So, you can select the algorithm you prefer:

- `cuid`: `import { createId } from '@paralleldrive/cuid2'`
- `uuid`: `import { v4 as uuid } from 'uuid'`
- `nanoid`: `import { nanoid } from 'nanoid'`
- `ulid`: `import { ulid } from 'ulid'`
- and any other function that returns a string! Let us know what's your favorite!

### @Fields.autoIncrement

This id value is determined by the underlying database on insert, and can't be updated through the API.

```ts
@Fields.autoIncrement()
id:number
```

### MongoDB ObjectId Field

To indicate that a field is of type object id, change it's `fieldTypeInDb` to `dbid`.

```ts
@Fields.string({
  dbName: '_id',
  valueConverter: {
    fieldTypeInDb: 'dbid',
  },
})
id: string = ''
```

## Enum Field

Enum fields allow you to define a field that can only hold values from a specific enumeration. The `@Fields.enum` decorator is used to specify that a field is an enum type. When using the `@Fields.enum` decorator, an automatic validation is added that checks if the value is valid in the specified enum.

```ts
@Fields.enum(() => Priority)
priority = Priority.Low;
```

In this example, the `priority` field is defined as an enum type using the `@Fields.enum` decorator. The `Priority` enum is passed as an argument to the decorator, ensuring that only valid `Priority` enum values can be assigned to the `priority` field. The `Validators.enum` validation is used and ensures that any value assigned to this field must be a member of the `Priority` enum, providing type safety and preventing invalid values.

## Literal Fields (Union of string values)

Literal fields let you restrict a field to a specific set of string values using the `@Fields.literal` decorator. This is useful for fields with a finite set of possible values.

```ts
@Fields.literal(() => ['open', 'closed', 'frozen', 'in progress'] as const)
status: 'open' | 'closed' | 'frozen' | 'in progress' = 'open';
```

In this example, we use the `as const` assertion to ensure that the array `['open', 'closed', 'frozen', 'in progress']` is treated as a readonly array, which allows TypeScript to infer the literal types 'open', 'closed', 'frozen', and 'in progress' for the elements of the array. This is important for the type safety of the `status` field.

The `status` field is typed as `'open' | 'closed' | 'frozen' | 'in progress'`, which means it can only hold one of these string literals. The `@Fields.literal` decorator is used to specify that the `status` field can hold values from this set of strings, and it uses the `Validators.in` validator to ensure that the value of `status` matches one of the allowed values.

For better reusability and maintainability, and to follow the DRY (Don't Repeat Yourself) principle, it is recommended to refactor the literal type and the array of allowed values into separate declarations:

```ts
const statuses = ['open', 'closed', 'frozen', 'in progress'] as const;
type StatusType = typeof statuses[number];

@Fields.literal(() => statuses)
status: StatusType = 'open';
```

In this refactored example, `statuses` is a readonly array of the allowed values, and `StatusType` is a type derived from the elements of `statuses`. The `@Fields.literal` decorator is then used with the `statuses` array, and the `status` field is typed as `StatusType`. This approach makes it easier to manage and update the allowed values for the `status` field, reducing duplication and making the code more robust and easier to maintain.

## ValueListFieldType

### Overview

The `ValueListFieldType` is useful in cases where simple enums and unions are not enough, such as when you want to have more properties for each value. For example, consider representing countries where you want to have a country code, description, currency, and international phone prefix.

### Defining a ValueListFieldType

Using enums or union types for this purpose can be challenging. Instead, you can use the `ValueListFieldType`:

```ts
@ValueListFieldType()
export class Country {
  static us = new Country('us', 'United States', 'USD', '1')
  static canada = new Country('ca', 'Canada', 'CAD', '1')
  static france = new Country('fr', 'France', 'EUR', '33')

  constructor(
    public id: string,
    public label: string,
    public currency: string,
    public phonePrefix: string,
  ) {}
}
```

### Using in an Entity

In your entity, you can define the field as follows:

```ts
@Field(() => Country)
country: Country = Country.us;
```

### Accessing Properties

The property called `id` will be stored in the database and used through the API, while in the code itself, you can use each property:

```ts
call('+' + person.country.phonePrefix + person.phone)
```

Note: Only the `id` property is saved in the database and used in the API. Other properties, such as `label`, `currency`, and `phonePrefix`, are only accessible in the code and are not persisted in the database.

### Getting Optional Values

To get the optional values for `Country`, you can use the `getValueList` function, which is useful for populating combo boxes:

```ts
console.table(getValueList(Country))
```

### Special Properties: id and label

The `id` and `label` properties are special in that the `id` will be used to save and load from the database, and the `label` will be used as the display value.

### Automatic Generation of id, caption and label

If `id` and/or `caption` & `label` are not provided, they are automatically generated based on the static member name. For example:

```ts
@ValueListFieldType()
export class TaskStatus {
  static open = new TaskStatus() // { id: 'open', label: 'Open' }
  static closed = new TaskStatus() // { id: 'closed', label: 'Closed' }

  id!: string
  label!: string
  constructor() {}
}
```

In this case, the `open` member will have an `id` of `'open'` and a `label` of `'Open'`, and similarly for the `closed` member.

### Handling Partial Lists of Values

In cases where you only want to generate members for a subset of values, you can use the `getValues` option of `@ValueListFieldType` to specify which values should be included:

```ts
@ValueListFieldType({
  getValues: () => [
    Country.us,
    Country.canada,
    Country.france,
    { id: 'uk', label: 'United Kingdom', currency: 'GBP', phonePrefix: '44' }
  ]
})
```

This approach is useful when you want to limit the options available for a field to a specific subset of values, without needing to define all possible values as static members.

::: warning Warning: TypeScript may throw an error similar to `Uncaught TypeError: Currency_1 is not a constructor`.
This happens in TypeScript versions <5.1.6 and target es2022. It's a TypeScript bug. To fix it, upgrade to version >=5.1.6 or change the target from es2022. Alternatively, you can call the `ValueListFieldType` decorator as a function after the type:

```ts
export class TaskStatus {
  static open = new TaskStatus()
  static closed = new TaskStatus()

  id!: string
  label!: string
  constructor() {}
}
ValueListFieldType()(TaskStatus)
```

:::

### Summary

The `ValueListFieldType` enables the creation of more complex value lists that provide greater flexibility and functionality for your application's needs beyond what enums and unions can offer. By allowing for additional properties and partial lists of values, it offers a versatile solution for representing and managing data with multiple attributes.

## Control Field Type in Database

In some cases, you may want to explicitly specify the type of a field in the database. This can be useful when you need to ensure a specific data type or precision for your field. To control the field type in the database, you can use the `fieldTypeInDb` option within the `valueConverter` property of a field decorator.

For example, if you want to ensure that a numeric field is stored as a decimal with specific precision in the database, you can specify the `fieldTypeInDb` as follows:

```ts
@Fields.number({
  valueConverter: {
    fieldTypeInDb: 'decimal(16,8)'
  }
})
price=0;
```

In this example, the `price` field will be stored as a `decimal` with 16 digits in total and 8 digits after the decimal point in the database. This allows you to control the storage format and precision of numeric fields in your database schema.

## Creating Custom Field Types

Sometimes, you may need to create custom field types to handle specific requirements or use cases in your application. By creating custom field types, you can encapsulate the logic for generating, validating, and converting field values.

### Example: Creating a Custom ID Field Type with NanoID

NanoID is a tiny, secure, URL-friendly, unique string ID generator. You can create a custom field type using NanoID to generate unique IDs for your entities. Here's an example of how to create a custom NanoID field type:

```typescript
import { nanoid } from 'nanoid'
import { Fields, type FieldOptions } from 'remult'

export function NanoIdField<entityType = any>(
  ...options: FieldOptions<entityType, string>[]
) {
  return Fields.string<entityType>(
    {
      allowApiUpdate: false, // Disallow updating the ID through the API
      defaultValue: () => nanoid(), // Generate a new NanoID as the default value
      saving: (_, record) => {
        if (!record.value) {
          record.value = nanoid() // Generate a new NanoID if the value is not set
        }
      },
    },
    ...options,
  )
}
```

In this example, the `NanoIdField` function creates a custom field type based on the `Fields.string` type. It uses the `nanoid` function to generate a unique ID as the default value and ensures that the ID is generated before saving the record if it hasn't been set yet. This custom field type can be used in your entities to automatically generate and assign unique IDs using NanoID.

## Customize DB Value Conversions

Sometimes you want to control how data is saved to the db, or the dto object.
You can do that using the `valueConverter` option.

For example, the following code will save the `tags` as a comma separated string in the db.

```ts
@Fields.object<Task, string[]>({
  valueConverter: {
    toDb: x => (x ? x.join(",") : undefined),
    fromDb: x => (x ? x.split(",") : undefined)
  }
})
tags: string[] = []
```

You can also refactor it to create your own FieldType

```ts
import { Field, FieldOptions, Remult } from 'remult'

export function CommaSeparatedStringArrayField<entityType = any>(
  ...options: (
    | FieldOptions<entityType, string[]>
    | ((options: FieldOptions<entityType, string[]>, remult: Remult) => void)
  )[]
) {
  return Fields.object(
    {
      valueConverter: {
        toDb: (x) => (x ? x.join(',') : undefined),
        fromDb: (x) => (x ? x.split(',') : undefined),
      },
    },
    ...options,
  )
}
```

And then use it:

```ts{9}
@CommaSeparatedStringArrayField()
tags: string[] = []
```

There are several ready made valueConverters included in the `remult` package, which can be found in `remult/valueConverters`

## Class Fields

Sometimes you may want a field type to be a class, you can do that, you just need to provide an implementation for its transition from and to JSON.

For example:

```ts
export class Phone {
  constructor(public phone: string) {}
  call() {
    window.open('tel:' + this.phone)
  }
}

@Entity('contacts')
export class Contact {
  //...
  @Field<Contact, Phone>(() => Phone, {
    valueConverter: {
      fromJson: (x) => (x ? new Phone(x) : undefined!),
      toJson: (x) => (x ? x.phone : undefined!),
    },
  })
  phone?: Phone
}
```

Alternatively you can decorate the `Phone` class with the `FieldType` decorator, so that whenever you use it, its `valueConverter` will be used.

```ts
@FieldType<Phone>({
  valueConverter: {
    fromJson: (x) => (x ? new Phone(x) : undefined!),
    toJson: (x) => (x ? x.phone : undefined!),
  },
})
export class Phone {
  constructor(public phone: string) {}
  call() {
    window.open('tel:' + this.phone)
  }
}

@Entity('contacts')
export class Contact {
  //...
  @Field(() => Phone)
  phone?: Phone
}
```



# Entities - Relations

# Relations Between Entities

::: tip **Interactive Learning Available! 🚀**

Looking to get hands-on with this topic? Try out our new [**interactive tutorial**](https://learn.remult.dev/in-depth/1-relations/1-many-to-one) on Relations, where you can explore and practice directly in the browser. This guided experience offers step-by-step lessons to help you master relations in Remult with practical examples and exercises.

[Click here to dive into the interactive tutorial on Relations!](https://learn.remult.dev/in-depth/1-relations/1-many-to-one)

:::

### Understanding Entity Relations in Remult

In Remult, entity relations play a useful role in modeling and navigating the complex relationships that exist within your data. To illustrate this concept, we will use two primary entities: `Customer` and `Order`. These entities will serve as the foundation for discussing various types of relations and how to define and work with them .

To experiment with these entities online, you can access the following CodeSandbox link, which is preconfigured with these two entities and a postgres database:

[CodeSandbox - Remult Entity Relations Example](https://codesandbox.io/p/devbox/remult-postgres-demo-f934f8)

Feel free to explore and experiment with the provided entities and their relations in the CodeSandbox environment.

#### Customer Entity

```typescript
// customer.ts

import { Entity, Fields } from 'remult'

@Entity('customers')
export class Customer {
  @Fields.id()
  id = ''
  @Fields.string()
  name = ''
  @Fields.string()
  city = ''
}
```

The `Customer` entity represents individuals or organizations with attributes such as an ID, name, and city. Each customer can be uniquely identified by their `id`.

#### Order Entity

```typescript
// order.ts

import { Entity, Fields } from 'remult'

@Entity('orders')
export class Order {
  @Fields.id()
  id = ''
  @Fields.string()
  customer = ''
  @Fields.number()
  amount = 0
}
```

The `Order` entity represents transactions or purchases made by customers. Each order is associated with a `customer`, representing the customer who placed the order, and has an `amount` attribute indicating the total purchase amount.

Throughout the following discussion, we will explore how to define and use relations between these entities, enabling you to create sophisticated data models and efficiently query and manipulate data using Remult. Whether you are dealing with one-to-one, one-to-many, or many-to-many relationships, understanding entity relations is essential for building robust and feature-rich applications with Remult.

## Simple Many-to-One

In Remult, many-to-one relations allow you to establish connections between entities, where multiple records of one entity are associated with a single record in another entity. Let's delve into a common use case of a many-to-one relation, specifically the relationship between the `Order` and `Customer` entities.

### Defining the Relation

To establish a many-to-one relation from the `Order` entity to the `Customer` entity, you can use the `@Relations.toOne()` decorator in your entity definition:

```typescript
// order.ts

import { Entity, Fields, Relations } from 'remult'
import { Customer } from '../customer.js'

@Entity('orders')
export class Order {
  @Fields.id()
  id = ''
  @Fields.string() // [!code --]
  customer = '' // [!code --]
  @Relations.toOne(() => Customer) // [!code ++]
  customer?: Customer // [!code ++]
  @Fields.number()
  amount = 0
}
```

In this example, each `Order` is associated with a single `Customer`. The `customer` property in the `Order` entity represents this relationship.

### Fetching Relational Data

When querying data that involves a many-to-one relation, you can use the `include` option to specify which related entity you want to include in the result set. In this case, we want to include the associated `Customer` when querying `Order` records.

Here's how you can include the relation in a query using Remult:

```typescript{2-4}
const orders = await repo(Order).find({
  include: {
    customer: true,
  },
})
```

#### Resulting Data Structure

The result of the query will contain the related `Customer` information within each `Order` record, creating a nested structure.

Here's an example result of running `JSON.stringify` on the `orders` array:

```json
[
  {
    "id": "adjkzsio3efees8ew0wnsqma",
    "customer": {
      "id": "m4ozs74onwwroav3o1xs1qi8",
      "name": "Larkin - Fadel",
      "city": "London"
    },
    "amount": 90
  },
  {
    "id": "gefhsed1clknmogcgiigo9jo",
    "customer": {
      "id": "m4ozs74onwwroav3o1xs1qi8",
      "name": "Larkin - Fadel",
      "city": "London"
    },
    "amount": 3
  }
]
```

As shown in the result, each `Order` object contains a nested `customer` object, which holds the details of the associated customer, including their `id`, `name`, and `city`. This structured data allows you to work seamlessly with the many-to-one relationship between `Order` and `Customer` entities .

### Querying a Single Item

To retrieve a single `Order` item along with its associated `Customer`, you can use the `findFirst` method provided by your repository (`orderRepo` in this case). Here's an example of how to perform this query:

```typescript
const singleOrder = await orderRepo.findFirst(
  {
    id: 'adjkzsio3efees8ew0wnsqma',
  },
  {
    include: {
      customer: true,
    },
  },
)
```

### Relation Loading

In Remult, by default, a relation is not loaded unless explicitly specified in the `include` statement of a query. This behavior ensures that you only load the related data you require for a specific task, optimizing performance and minimizing unnecessary data retrieval.

Here's an example:

```typescript
// Query without including the 'customer' relation
const ordersWithoutCustomer = await repo(Order).find({})
```

In the above query, the `customer` relation will not be loaded and have the value of `undefined` because it is not specified in the `include` statement.

#### Overriding Default Behavior with `defaultIncluded`

Sometimes, you may have scenarios where you want a relation to be included by default in most queries, but you also want the flexibility to exclude it in specific cases. Remult allows you to control this behavior by using the `defaultIncluded` setting in the relation definition.

```typescript
@Relations.toOne(() => Customer, {
  defaultIncluded: true, // [!code ++]
})
customer = "";
```

In this example, we set `defaultIncluded` to `true` for the `customer` relation in the `Order` entity. This means that, by default, the `customer` relation will be loaded in most queries unless explicitly excluded.

#### Example: Excluding `customer` Relation in a Specific Query

```typescript
const orders = await orderRepo.find({
  include: {
    customer: false, // [!code ++]
  },
})
```

In this query, we override the default behavior by explicitly setting `customer: false` in the `include` statement. This instructs Remult not to load the `customer` relation for this specific query, even though it is set to be included by default.

By combining the default behavior with the ability to override it in specific queries, Remult provides you with fine-grained control over relation loading, ensuring that you can optimize data retrieval based on your application's requirements and performance considerations.

## Advanced Many-to-One

In certain scenarios, you may require more granular control over the behavior of relations and want to access specific related data without loading the entire related entity. Remult provides advanced configuration options to meet these requirements. Let's explore how to achieve this level of control through advanced relation configurations.

### Custom Relation Field

In Remult, you can define custom relation fields that allow you to access the `id` without loading the entire related entity. To define a custom relation field, follow these steps:

#### Step 1: Define a Custom Field in the Entity

In your entity definition, define a custom field that will hold the identifier or key of the related entity. This field serves as a reference to the related entity without loading the entity itself.

```typescript{5-8}
@Entity("orders")
export class Order {
  @Fields.id()
  id = "";
  @Fields.string() // [!code ++]
  customerId = ""; // Custom field to hold the related entity's identifier // [!code ++]
  @Relations.toOne<Order, Customer>(() => Customer, "customerId")  // [!code ++]
  @Relations.toOne(() => Customer) // [!code --]
  customer?: Customer;
  @Fields.number()
  amount = 0;
}
```

In this example, we define a custom field called `customerId`, which stores the identifier of the related `Customer` entity.

#### Step 2: Define the Relation Using `toOne`

Use the `@Relations.toOne` decorator to define the relation, specifying the types for the `fromEntity` and `toEntity` in the generic parameters. Additionally, provide the name of the custom field (in this case, `"customerId"`) as the third argument.

```typescript
@Entity('orders')
export class Order {
  @Fields.id()
  id = ''
  @Fields.string()
  customerId = '' // Custom field to hold the related entity's identifier
  @Relations.toOne<Order, Customer>(() => Customer, 'customerId') // [!code ++]
  customer = ''
  @Fields.number()
  amount = 0
}
```

This configuration establishes a relation between `Order` and `Customer` using the `customerId` field as the reference.

#### Migrating from a Simple `toOne` Relation to a Custom Field Relation with Existing Data

When transitioning from a simple `toOne` relation to a custom field relation in Remult and you already have existing data, it's important to ensure a smooth migration. In this scenario, you need to make sure that the newly introduced custom field (`customerId` in this case) can access the existing data in your database. This is accomplished using the `dbName` option. Here's how to perform this migration:

##### 1. Understand the Existing Data Structure

Before making any changes, it's crucial to understand the structure of your existing data. In the case of a simple `toOne` relation, there may be rows in your database where a field (e.g., `customer`) holds the identifier of the related entity.

##### 2. Define the Custom Field with `dbName`

When defining the custom field in your entity, use the `dbName` option to specify the name of the database column where the related entity's identifier is stored. This ensures that the custom field (`customerId` in this example) correctly accesses the existing data in your database.

```typescript
@Entity('orders')
export class Order {
  @Fields.id()
  id = ''
  @Fields.string({ dbName: 'customer' }) // Use dbName to match existing data // [!code ++]
  customerId = ''
  @Relations.toOne(() => Customer, 'customerId')
  customer?: Customer
  @Fields.number()
  amount = 0
}
```

In this example, we use the `dbName` option to specify that the `customerId` field corresponds to the `customer` column in the database. This mapping ensures that the custom field can access the existing data that uses the `customer` column for the related entity's identifier.

#### Using the `field` Option for Custom Relation Configuration

When you require additional customization for a relation field in Remult, you can utilize the field option to specify additional options for the related field.

```typescript
@Relations.toOne<Order, Customer>(() => Customer, {
  field: "customerId", // [!code ++]
  label: "The Customer",
})
```

In this example, we use the `field` option to define a custom relation between the `Order` and `Customer` entities. Here are some key points to understand about using the `field` option:

1. **Custom Relation Field**: The `field` option allows you to specify a custom field name (e.g., `"customerId"`) that represents the relationship between entities. This field can be used to access related data without loading the entire related entity.

2. **Additional Configuration**: In addition to specifying the `field`, you can include other options as well. In this example, we set the `label` option to provide a descriptive label for the relation field.

Using the `field` option provides you with granular control over how the relation field is configured and accessed . You can customize various aspects of the relation to meet your specific requirements, enhance documentation, and improve the overall usability of your codebase.

### Relation Based on Multiple Fields

In some scenarios, establishing a relation between entities requires considering multiple fields to ensure the correct association. Remult provides the flexibility to define relations based on multiple fields using the `fields` option. Here's how to create a relation based on multiple fields in Remult:

#### Defining Entities

Let's consider a scenario where both `Order` and `Customer` entities belong to specific branches, and we need also the `branchId` fields to ensure the correct association. First, define your entities with the relevant fields:

```typescript{0}
@Entity('customers')
export class Customer {
  @Fields.id()
  id = ''
  @Fields.number() // [!code ++]
  branchId = 0 // [!code ++]
  @Fields.string()
  name = ''
  @Fields.string()
  city = ''
}

@Entity('orders')
export class Order {
  @Fields.id()
  id = ''
  @Fields.number() // [!code ++]
  branchId = 0 // [!code ++]
  @Fields.string({ dbName: 'customer' })
  customerId = ''
  @Relations.toOne<Order, Customer>(() => Customer, {
    fields: {//[!code ++]
      branchId: 'branchId', // Field from Customer entity : Field from Order// [!code ++]
      id: 'customerId', // [!code ++]
    }, // [!code ++]
  })
  customer?: Customer
  @Fields.number()
  amount = 0
}
```

In this example, we have two entities: `Customer` and `Order`. Both entities have a `branchId` field that represents the branch they belong to. To create a relation based on these fields, we specify the `fields` option in the relation configuration.

#### Using the `fields` Option

In the `@Relations.toOne` decorator, use the `fields` option to specify the mapping between fields in the related entity (`Customer`) and your entity (`Order`). Each entry in the `fields` object corresponds to a field in the related entity and maps it to a field in your entity.

```typescript
@Relations.toOne<Order, Customer>(() => Customer, {
  fields: {// [!code ++]
    branchId: 'branchId', // Field from Customer entity : Field from Order// [!code ++]
    id: 'customerId',// [!code ++]
  },// [!code ++]
})
customer?: Customer;
```

In this configuration:

- `branchId` from the `Customer` entity is mapped to `branchId` in the `Order` entity.
- `id` from the `Order` entity is mapped to `customerId` in the `Customer` entity.

This ensures that the relation between `Order` and `Customer` is based on both the `branchId` and `customerId` fields, providing a comprehensive association between the entities.

By utilizing the `fields` option, you can create relations that consider multiple fields, ensuring accurate and meaningful associations between your entities in Remult.

## One-to-Many

In Remult, you can easily define a `toMany` relation to retrieve multiple related records. Let's consider a scenario where you want to retrieve a list of orders for each customer. We'll start with the basic `toOne` relation example and then add a `toMany` relation to achieve this:

#### Basic `toOne` Relation Example

First, let's define the `Customer` and `Order` entities with a basic `toOne` relation:

```typescript{9-10}
@Entity("customers")
export class Customer {
  @Fields.id()
  id = "";
  @Fields.string()
  name = "";
  @Fields.string()
  city = "";
}

@Entity("orders")
export class Order {
  @Fields.id()
  id = "";
  @Relations.toOne(() => Customer)
  customer?: Customer;
  @Fields.number()
  amount = 0;
}
```

In this initial setup:

- The `Order` entity has a property `customer`, which is decorated with `@Relations.toOne(() => Customer)`. This establishes a relation between an order and its associated customer.

### Adding a `toMany` Relation

Now, let's enhance this setup to include a `toMany` relation that allows you to retrieve a customer's orders:

```typescript
@Entity('customers')
export class Customer {
  @Fields.id()
  id = ''
  @Fields.string()
  name = ''
  @Fields.string()
  city = ''
  @Relations.toMany(() => Order) // [!code ++]
  orders?: Order[] // [!code ++]
}
```

In this updated configuration:

- The `Customer` entity has a property `orders`, which is decorated with `@Relations.toMany(() => Order)`. This indicates that a customer can have multiple orders.

With this setup, you can use the `orders` property of a `Customer` entity to retrieve all the orders associated with that customer. This provides a convenient way to access and work with a customer's orders.

By defining a `toMany` relation, you can easily retrieve and manage multiple related records, such as a customer's orders.

### Fetching Relational Data

To retrieve customers along with their associated order in Remult, you can use the `include` option in your query. Let's see how to fetch customers with their orders using the `include` option:

```typescript
const customers = await repo(Customer).find({
  include: {
    orders: true,
  },
})
```

In this code snippet:

- We first obtain a repository for the `Customer` entity using `repo(Customer)`.

- Next, we use the `find` method to query the `Customer` entity. Within the query options, we specify the `include` option to indicate that we want to include related records.

- Inside the `include` option, we specify `orders: true`, indicating that we want to fetch the associated orders for each customer.

As a result, the `customers` variable will contain an array of customer records, with each customer's associated orders included. This allows you to easily access and work with both customer and order data.

#### Resulting Data Structure

When you fetch customers along with their associated orders using the `include` option in Remult, the result will be an array that includes both customer and order data.

Here's an example result of running `JSON.stringify` on the `customers` array:

```json
[
  {
    "id": "ik68p3oxqg1ygdffpryqwkpw",
    "name": "Fay, Ebert and Sporer",
    "city": "London",
    "orders": [
      {
        "id": "m7m3xqyx4kwjaqcd0cu33q8g",
        "amount": 15
      },
      {
        "id": "rbkcrz6nc45zn4xfxmjise21",
        "amount": 10
      }
    ]
  }
]
```

In this example:

- Each customer is represented as an object with properties such as `id`, `name`, and `city`.

- The `orders` property within each customer object contains an array of associated order records.

- Each order record within the `orders` array includes properties like `id` and `amount`.

This structured result allows you to easily navigate and manipulate the data . You can access customer information as well as the details of their associated orders, making it convenient to work with related records in your application's logic and UI.

### Specifying Reference Fields

In Remult, you can specify a field or fields for `toMany` relations to have more control over how related records are retrieved. This can be useful when you want to customize the behavior of the relation. Here's how you can specify a field or fields for `toMany` relations:

#### Specifying a Single Field

To specify a single field for a `toMany` relation, you can use the `field` option. This option allows you to define the field in your entity that establishes the relation. For example:

```typescript
@Relations.toMany<Customer, Order>(() => Order, {
  field: "customer",
})
```

In this case, the `field` option is set to `"customer"`, indicating that the `customer` field in the `Order` entity establishes the relation between customers and their orders.

#### Specifying Multiple Fields

In some cases, you may need to specify multiple fields to establish a `toMany` relation. To do this, you can use the `fields` option, which allows you to define a mapping of fields between entities. Here's an example:

```typescript
@Relations.toMany<Customer, Order>(() => Order, {
  fields: {
    branchId: "branchId",
    customerId: "id",
  },
})
```

In this example, the `fields` option is used to specify that the `branchId` field in the `Order` entity corresponds to the `branchId` field in the `Customer` entity, and the `customerId` field in the `Order` entity corresponds to the `id` field in the `Customer` entity.

By specifying fields in this manner, you have fine-grained control over how the relation is established and how related records are retrieved. This allows you to tailor the behavior of `toMany` relations to your specific use case and data model.

### Customizing a `toMany` Relation

In Remult, you can exercise precise control over a `toMany` relation by utilizing the `findOptions` option. This option allows you to define specific criteria and behaviors for retrieving related records. Here's how you can use `findOptions` to fine-tune a `toMany` relation:

```typescript
@Relations.toMany<Customer, Order>(() => Order, {
  fields: {
    branchId: "branchId",
    customerId: "id",
  },
  findOptions: {
    limit: 5,
    orderBy: {
      amount: "desc",
    },
    where: {
      amount: { $gt: 10 },
    },
  },
})
```

In this example, we've specified the following `findOptions`:

- `limit: 5`: Limits the number of related records to 5. Only the first 5 related records will be included.

- `orderBy: { amount: "desc" }`: Orders the related records by the `amount` field in descending order. This means that records with higher `amount` values will appear first in the result.

- `where: { amount: { $gt: 10 } }`: Applies a filter to include only related records where the `amount` is greater than 10. This filters out records with an `amount` of 10 or lower.

By using `findOptions` in this manner, you gain precise control over how related records are retrieved and included in your query results. This flexibility allows you to tailor the behavior of the `toMany` relation to suit your specific application requirements and use cases.

#### Fine-Tuning a `toMany` Relation with `include`

In Remult, you can exercise even more control over a `toMany` relation by using the `include` option within your queries. This option allows you to further customize the behavior of the relation for a specific query. Here's how you can use `include` to fine-tune a `toMany` relation:

```typescript
const orders = await customerRepo.find({
  include: {
    orders: {
      limit: 10,
      where: {
        completed: true,
      },
    },
  },
})
```

In this code snippet:

- We use the `include` option within our query to specify that we want to include the related `orders` for each customer.

- Inside the `include` block, we can provide additional options to control the behavior of this specific inclusion. For example:
  - `limit: 10` limits the number of related orders to 10 per customer. This will override the `limit` set in the original relation.
  - `where: { completed: true }` filters the included orders to only include those that have been marked as completed.

The `where` option specified within `include` will be combined with the `where` conditions defined in the `findOptions` of the relation using an "and" relationship. This means that both sets of conditions must be satisfied for related records to be included.

Using `include` in this way allows you to fine-tune the behavior of your `toMany` relation to meet the specific requirements of each query, making Remult a powerful tool for building flexible and customized data retrieval logic in your application.

## Repository `relations`

In Remult, managing relationships between entities is a crucial aspect of working with your data. When dealing with a `toMany` relationship, Remult provides you with powerful tools through the repository's `relations` property to handle related rows efficiently, whether you want to retrieve them or insert new related records.

### Inserting Related Records

Consider a scenario where you have a `Customer` entity with a `toMany` relationship to `Order` entities. You can create a new customer and insert related orders in a straightforward manner:

```typescript
const customer = await customerRepo.insert({ name: 'Abshire Inc' })
await customerRepo.relations(customer).orders.insert([
  {
    amount: 5,
  },
  {
    amount: 7,
  },
])
```

In this example, you first create a new `Customer` entity with the name "Abshire Inc." Then, using the `relations` method, you access the related `orders`. By calling the `insert` method on the `orders` relation, you can add new order records. Remult automatically sets the `customer` field for these orders based on the specific customer associated with the `relations` call.

### Loading Unfetched Relations

Another powerful use of the `repository` methods is to load related records that were not initially retrieved. Let's say you have found a specific customer and want to access their related orders:

```typescript
const customerRepo = repo(Customer)
const customer = await customerRepo.findFirst({ name: 'Abshire Inc' })
const orders = await customerRepo.relations(customer).orders.find()
```

Here, you first search for a customer with the name "Abshire Inc." After locating the customer, you can use the `relations` method again to access their related orders. By calling the `find` method on the `orders` relation, you retrieve all related order records associated with the customer.

#### Contextual Repository: Tailored Operations for Related Data

The `relations` method serves as a specialized repository, tightly associated with the particular customer you supply to it. This dedicated repository offers a tailored context for performing operations related to the specific customer's connection to orders. It enables you to seamlessly find related records, insert new ones, calculate counts, and perform other relevant actions within the precise scope of that customer's relationship with orders. This versatile capability streamlines the management of intricate relationships in your application, ensuring your data interactions remain organized and efficient.

Remult's repository methods empower you to seamlessly manage and interact with related data, making it easier to work with complex data structures and relationships in your applications. Whether you need to insert related records or load unfetched relations, these tools provide the flexibility and control you need to handle your data efficiently.

---

### Fetching Unloaded `toOne` Relations with `findOne`

In addition to loading unfetched `toMany` relations, Remult offers a convenient way to retrieve `toOne` relations that were not initially loaded. This capability is especially useful when dealing with many-to-one relationships.

Consider the following example, where we have a many-to-one relation between orders and customers. We want to fetch the customer related to a specific order, even if we didn't load it initially:

```ts
const orderRepo = repo(Order)
const order = await orderRepo.findFirst({ id: 'm7m3xqyx4kwjaqcd0cu33q8g' })
const customer = await orderRepo.relations(order).customer.findOne()
```

In this code snippet:

1. We first obtain the order using the `findFirst` function, providing the order's unique identifier.
2. Next, we use the `relations` method to access the repository's relations and then chain the `customer` relation using dot notation.
3. Finally, we call `findOne()` on the `customer` relation to efficiently retrieve the related customer information.

This approach allows you to access and load related data on-demand, providing flexibility and control over your data retrieval process. Whether you're working with loaded or unloaded relations, Remult's intuitive functions give you the power to seamlessly access the data you need.

---

You can seamlessly incorporate this extension into the "Loading Unfetched Relations" section of your documentation to provide a comprehensive overview of working with both `toMany` and `toOne` relations.

---

### Accessing Relations with `activeRecord`

If you're following the `activeRecord` pattern and your entity inherits from `EntityBase` or `IdEntity`, you can access relations directly from the entity instance. This approach offers a convenient and straightforward way to work with relations.

#### Inserting Related Records

You can insert related records directly from the entity instance. For example, consider a scenario where you have a `Customer` entity and a `toMany` relation with `Order` entities. Here's how you can insert related orders for a specific customer:

```ts
const customer = await customerRepo.insert({ name: 'Abshire Inc' })
await customer._.relations.orders.insert([
  {
    amount: 5,
  },
  {
    amount: 7,
  },
])
```

In this code:

- We create a new `Customer` instance using `customerRepo.insert()` and set its properties.
- Using `customer._.relations.orders`, we access the `orders` relation of the customer.
- We insert two orders related to the customer by calling `.insert()` on the `orders` relation.

#### Retrieving Related Records

Fetching related records is just as straightforward. Let's say you want to find a customer by name and then retrieve their related orders:

```ts
const customer = await customerRepo.findFirst({ name: 'Abshire Inc' })
const orders = await customer._.relations.orders.find()
```

In this code:

- We search for a customer with the specified name using `customerRepo.findFirst()`.
- Once we have the customer instance, we access their `orders` relation with `customer._.relations.orders`.
- We use `.find()` to retrieve all related orders associated with the customer.

Using the `activeRecord` pattern and direct access to relations simplifies the management of related data, making it more intuitive and efficient.

## Many-to-Many

In Remult, you can effectively handle many-to-many relationships between entities by using an intermediate table. This approach is especially useful when you need to associate multiple instances of one entity with multiple instances of another entity. In this section, we'll walk through the process of defining and working with many-to-many relationships using this intermediate table concept.

#### Entity Definitions:

To illustrate this concept, let's consider two entities: `Customer` and `Tag`. In this scenario, multiple customers can be associated with multiple tags.

```ts
@Entity('customers')
export class Customer {
  @Fields.id()
  id = ''
  @Fields.string()
  name = ''
  @Fields.string()
  city = ''
}

@Entity('tags')
export class Tag {
  @Fields.id()
  id = ''
  @Fields.string()
  name = ''
}
```

### Intermediate Table

To establish this relationship, we'll create an intermediate table called `tagsToCustomers`. In this table, both `customerId` and `tagId` fields are combined as the primary key.

```ts
@Entity<TagsToCustomers>('tagsToCustomers', {
  id: {
    customerId: true,
    tagId: true,
  },
})
export class TagsToCustomers {
  @Fields.string()
  customerId = ''
  @Fields.string()
  tagId = ''
  @Relations.toOne<TagsToCustomers, Tag>(() => Tag, 'tagId')
  tag?: Tag
}
```

- To uniquely identify associations between customers and tags in a many-to-many relationship, we use the combined `customerId` and `tagId` fields as the primary key, specified using the 'id' option in the `@Entity` decorator.

- In this scenario, we've defined a `toOne` relation to the `Tag` entity within the `TagsToCustomers` entity to efficiently retrieve tags associated with a specific customer. This approach simplifies the management of many-to-many relationships while ensuring unique identification of each association.

Now, let's enhance our customer entity with a toMany relationship, enabling us to fetch all of its associated tags effortlessly.

```ts
@Entity('customers')
export class Customer {
  @Fields.id()
  id = ''
  @Fields.string()
  name = ''
  @Fields.string()
  city = ''
  @Relations.toMany(() => TagsToCustomers, 'customerId') // [!code ++]
  tags?: TagsToCustomers[] // [!code ++]
}
```

### Working with Many-to-Many Relationships

Let's explore how to interact with many-to-many relationships using an intermediate table in Remult.

#### 1. Adding Tags to a Customer:

To associate a tag with a customer, consider the follow code:

```ts
const tags = await repo(Tag).insert([
  { name: 'vip' },
  { name: 'hot-lead' },
  { name: 'influencer' },
  { name: 'manager' },
]) // Create the tags

const customerRepo = repo(Customer)
const customer = await customerRepo.findFirst({ name: 'Abshire Inc' })
await customerRepo
  .relations(customer)
  .tags.insert([{ tag: tags[0] }, { tag: tags[2] }])
```

Here's an explanation of what's happening in this code:

1. We first insert some tags into the "tags" entity.

2. We then create a repository instance for the "customer" entity using `repo(Customer)`.

3. We retrieve a specific customer by searching for one with the name "Abshire Inc" using `customerRepo.findFirst({ name: "Abshire Inc" })`. The `customer` variable now holds the customer entity.

4. To associate tags with the customer, we use the `relations` method provided by the repository. This method allows us to work with the customer's related entities, in this case, the "tags" relation to the TagsToCustomers entity.

5. Finally, we call the `insert` method on the "tags" relationship and provide an array of tag objects to insert. In this example, we associate the customer with the "vip" tag and the "influencer" tag by specifying the tags' indices in the `tags` array.

**2. Retrieving Tags for a Customer:**
To fetch the tags associated with a specific customer:

```ts
const customer = await customerRepo.findFirst(
  { name: 'Abshire Inc' },
  {
    include: {
      tags: {
        include: {
          tag: true,
        },
      },
    },
  },
)
```

In this code, we're querying the "customer" entity to find a customer named "Abshire Inc." We're also including the related "tags" for that customer, along with the details of each tag. This allows us to fetch both customer and tag data in a single query, making it more efficient when working with related entities.

### Resulting Data Structure

Here's an example result of running `JSON.stringify` on the `customer` object:

```json
{
  "id": "fki6t24zkykpljvh4jurzs97",
  "name": "Abshire Inc",
  "city": "New York",
  "tags": [
    {
      "customerId": "fki6t24zkykpljvh4jurzs97",
      "tagId": "aewm0odq9758nopgph3x7brt",
      "tag": {
        "id": "cf8xv3myluc7pmsgez3p9hn9",
        "name": "vip"
      }
    },
    {
      "customerId": "fki6t24zkykpljvh4jurzs97",
      "tagId": "aewm0odq9758nopgph3x7brt",
      "tag": {
        "id": "aewm0odq9758nopgph3x7brt",
        "name": "influencer"
      }
    }
  ]
}
```

Utilizing an intermediate table for managing many-to-many relationships in Remult allows for a flexible and efficient approach to handle complex data associations. Whether you are connecting customers with tags or other entities, this method provides a powerful way to maintain data integrity and perform queries effectively within your application.

---

In this guide, we've explored the essential concepts of managing entity relations within the Remult library. From one-to-one to many-to-many relationships, we've covered the declaration, customization, and querying of these relations. By understanding the nuances of entity relations, users can harness the full potential of Remult to build robust TypeScript applications with ease.


# Relations - Filtering and Relations

# Filtering and Relations

::: tip **Interactive Learning Available! 🚀**

Looking to get hands-on with this topic? Try out our new [**interactive tutorial**](https://learn.remult.dev/in-depth/4-filtering/1-custom-filters) on Filtering relations, where you can explore and practice directly in the browser. This guided experience offers step-by-step lessons to help you master filtering in Remult with practical examples and exercises.

[Click here to dive into the interactive tutorial on Filtering and Relations!](https://learn.remult.dev/in-depth/4-filtering/1-custom-filters)

:::

In this article, we'll discuss several relevant techniques for one-to-many relations.
Consider the following scenario where we have a customer entity and an Orders entity.

We'll use the following entities and data for this article.

```ts
import { Entity, Field, Fields, remult, Relations } from 'remult'

@Entity('customers')
export class Customer {
  @Fields.autoIncrement()
  id = 0
  @Fields.string()
  name = ''
  @Fields.string()
  city = ''
  @Relations.toMany(() => Order)
  orders?: Order[]
}

@Entity('orders')
export class Order {
  @Fields.autoIncrement()
  id = 0
  @Relations.toOne(() => Customer)
  customer!: Customer
  @Fields.number()
  amount = 0
}
```

::: tip Use Case in this article
Let's say that we want to filter all the orders of customers who are in London.

Let's have a look at the different options to achieve this.
:::

## Option 1 - Use In Statement

Add the `where` inline to the `find` method.

```ts
console.table(
  await repo(Order).find({
    where: {
      customer: await repo(Customer).find({
        where: {
          city: 'London',
        },
      }),
    },
  }),
)
```

## Option 2 - Use Custom Filter

We can refactor this to a custom filter that will be easier to use and will run on the backend

```ts
import { Filter } from 'remult'

@Entity('orders', { allowApiCrud: true })
export class Order {
  //...
  static filterCity = Filter.createCustom<Order, { city: string }>(
    async ({ city }) => ({
      customer: await repo(Customer).find({ where: { city } }),
    }),
  )
}
```

And then we can use it:

```ts
console.table(
  await repo(Order).find({
    where: Order.filterCity({
      city: 'London',
    }),
  }),
)
```

## Option 3 - Custom Filter (SQL)

We can improve on the custom filter by using the database's in statement capabilities:

```ts
import { SqlDatabase } from 'remult'

@Entity('orders', { allowApiCrud: true })
export class Order {
  //...
  static filterCity = Filter.createCustom<Order, { city: string }>(
    async ({ city }) =>
      SqlDatabase.rawFilter(
        ({ param }) =>
          `customer in (select id from customers where city = ${param(city)})`,
      ),
  )
}
```

We can also reuse the entity definitions by using `dbNamesOf` and `filterToRaw`

```ts
import { dbNamesOf } from 'remult'

@Entity('orders', { allowApiCrud: true })
export class Order {
  //...
  static filterCity = Filter.createCustom<Order, { city: string }>(
    async ({ city }) => {
      const orders = await dbNamesOf(Order)
      const customers = await dbNamesOf(Customer)
      return SqlDatabase.rawFilter(
        async ({ filterToRaw }) =>
          `${orders.customer} in 
               (select ${customers.id} 
                  from ${customers} 
                 where ${await filterToRaw(Customer, { city })})`,
      )
    },
  )
}
```

## Option 4 - sqlExpression field

```ts
@Entity('orders', { allowApiCrud: true })
export class Order {
  //...
  @Fields.string<Order>({
    sqlExpression: async () => {
      const customer = await dbNamesOf(Customer)
      const order = await dbNamesOf(Order)
      return `(
          select ${customer.city}
            from ${customer}
           where ${customer.id} = ${order.customer}
          )`
    },
  })
  city = ''
}
```

- This adds a calculated `city` field to the `Order` entity that we can use to order by or filter

```ts
console.table(
  await repo(Order).find({
    where: {
      city: 'London',
    },
  }),
)
```

::: details Side Note
In this option, `city` is always calculated, and the `sqlExpression` is always executed. Not a big deal, but it's woth mentioning. (Check out Option 5 for a solution)
:::

## Option 5 - Dedicated entity

```ts
export class OrderWithCity extends Order {
  @Fields.string<Order>({
    sqlExpression: async () => {
      const customer = await dbNamesOf(Customer)
      const order = await dbNamesOf(Order)
      return `(
          select ${customer.city}
            from ${customer}
           where ${customer.id} = ${order.customer}
          )`
    },
  })
  city = ''
}
```

Like this, in your code, you can use `OrderWithCity` or `Order` depending on your needs.

::: tip
As `OrderWithCity` extends `Order`, everything in `Order` is also available in `OrderWithCity` 🎉.
:::



# Entities - Lifecycle Hooks

# Entity Lifecycle Hooks

In Remult, you can take advantage of Entity Lifecycle Hooks to add custom logic and actions at specific stages of an entity's lifecycle. There are five lifecycle events available: `validation`, `saving`, `saved`, `deleting`, and `deleted`. These hooks allow you to perform actions or validations when specific events occur in the entity's lifecycle.

## Validation

- **Runs On**: Backend and Frontend.
- **Purpose**: To perform validations on the entity's data before saving. This is the best place to check how individual fields in entity relate to each other.
- **Example**:
  ```ts
  @Entity<Task>("tasks", {
    validation: async (task, e) => {
      // simple validation of single field
      if (task.title.length < 5) {
        e.fields.collection.error = "Task title must be at least 5 characters long."
      }

      // checking few fields for joint validity
      if (task.completed && task.assignedToId === null){
        throw new Error(`Task ${task.title} must be assigned to someone before beeing completed.`)
      }
    },
  })
  ```

  ::: tip
  You can run custom validation like in this example to check separate fields one by one as we do with `title.length`, but probably better place to do it with [field validation](./validation.md).
  :::

  ::: tip
  When validation runs on backend it do not load [relations](./entity-relations.md) automatically! On server side hook receives only relation primary keys and relation data is `undefined` if you try to use it. There is two ways to overcome it:
  * `load()` relation:
  ```ts
  @Entity<Order>("orders", {
    validation: async (order, e) => {
      // option 1 - load relation when you need it
      await e.fields.items.load()
      if (length(order.items) > 3 && order.destinationCountry == 'US') {
        throw new Error("We can't ship such large orders to USA! :-(");
      }
    },
  })
  ```

  * add [`relationExists`](./ref_validators#relationexists) validation to field:
  ```ts
  @Relations.toMany(() => Items, {
    // option 2 - relation is loaded by byproduct of this validation
    validate: Validators.relationExists
  })
  items?: Item[];
  ```
  :::

## Saving

- **Runs On**: Backend (or Frontend if using a local frontend database).
- **Purpose**: To execute custom logic before an entity is saved.
- **Example**:
  ```ts
  @Entity<Task>("tasks", {
    saving: async (task, e) => {
      if (e.isNew) {
        task.createdAt = new Date(); // Set the creation date for new tasks.
      }
      task.lastUpdated = new Date(); // Update the last updated date.
    },
  })
  ```

## Saved

- **Runs On**: Backend (or Frontend if using a local frontend database).
- **Purpose**: To perform actions after an entity has been successfully saved.
- **Example**: Useful for triggering additional processes or updates after saving.

## Deleting

- **Runs On**: Backend (or Frontend if using a local frontend database).
- **Purpose**: To execute custom logic before an entity is deleted.
- **Example**: You can use this to ensure related data is properly cleaned up or archived.

## Deleted

- **Runs On**: Backend (or Frontend if using a local frontend database).
- **Purpose**: To perform actions after an entity has been successfully deleted.
- **Example**: Similar to the `saved` event, this is useful for any post-deletion processes.

## Field Saving Hook

Additionally, you can define a field-specific `saving` hook that allows you to perform custom logic on a specific field before the entity `saving` hook. It has the following signature:

```ts
@Fields.Date<Task>({
  saving: (task, fieldRef, e) => {
    if (e.isNew) task.createdAt = new Date()
  },
})
createdAt = new Date()
```

or using the fieldRef

```ts
@Fields.Date({
  saving: (_, fieldRef, e) => {
    if (e.isNew) fieldRef.value = new Date()
  },
})
createdAt = new Date()
```

You can use the field `saving` hook to perform specialized actions on individual fields during the entity's saving process.

## Lifecycle Event Args

Each lifecycle event receives an instance of the relevant entity and an event args of type `LifecycleEvent`. The `LifecycleEvent` object provides various fields and methods to interact with the entity and its context. Here are the fields available in the `LifecycleEvent`:

- `isNew`: A boolean indicating whether the entity is new (being created).
- `fields`: A reference to the entity's fields, allowing you to access and modify field values.
- `id`: The ID of the entity.
- `originalId`: The original ID of the entity, which may differ during certain operations.
- `repository`: The repository associated with the entity.
- `metadata`: The metadata of the entity, providing information about its structure.
- `preventDefault()`: A method to prevent the default behavior associated with the event.
- `relations`: Access to repository relations for the entity, allowing you to work with related data.

## Example Usage

Here's an example of how to use Entity Lifecycle Hooks to add custom logic to the `saving` event:

```ts
@Entity<Task>("tasks", {
  saving: async (task, e) => {
    if (e.isNew) {
      task.createdAt = new Date(); // Set the creation date for new tasks.
    }
    task.lastUpdated = new Date(); // Update the last updated date.
  },
})
```

In this example, we've defined a `saving` event for the `Task` entity. When a task is being saved, the event handler is called. If the task is new (not yet saved), we set its `createdAt` field to the current date. In either case, we update the `lastUpdated` field with the current date.

Entity Lifecycle Hooks provide a powerful way to customize the behavior of your entities and ensure that specific actions or validations are performed at the right time in the entity's lifecycle. You can use these hooks to streamline your application's data management and enforce business rules.



# Entities - Migrations

# Migrations

Managing database schemas is crucial in web development. Traditional migration approaches introduce complexity and risks. Remult, designed for data-driven web apps with TypeScript, offers a simpler method.

## You Don't Necessarily Need Migrations

Migration files are standard but can complicate database schema management. They're prone to errors, potentially leading to conflicts or downtime. Remult proposes a streamlined alternative: automatic schema synchronization. This approach simplifies schema management by ensuring your database schema aligns with your application code without the manual overhead of traditional migrations.

### Embracing Schema Synchronization with Remult

Remult offers an alternative: automatic schema synchronization. **By default, Remult checks for and synchronizes your database schema with the entity types** provided in the `RemultServerOptions.entities` property when the server loads. This feature automatically adds any missing tables or columns, significantly simplifying schema management.

::: tip No Data Loss with Remult's Safe Schema Updates
**Remult's schema synchronization** ensures **safe and automatic updates** to your database schema. By only adding new tables or columns without altering existing ones, Remult prevents data loss. This design offers a secure way to evolve your application's database schema.
:::

#### Disabling Automatic Schema Synchronization

For manual control, Remult allows disabling automatic schema synchronization:

```typescript
const api = remultApi({
  entities: [], // Your entities here
  ensureSchema: false, // Disables automatic schema synchronization, Default: true
})
```

#### Manually Triggering Schema Synchronization

In certain scenarios, you might want to manually trigger the `ensureSchema` function to ensure that your database schema is up-to-date with your entity definitions. Here's how you can do it:

```ts
remult.dataProvider.ensureSchema!(entities.map((x) => repo(x).metadata))
```

## Quick Start: Introducing Migrations to Your Application

Introducing migrations to your Remult application involves a few straightforward steps. The goal is to ensure that your migrations and API share the same data provider and entity definitions. Here's how you can do it:

### 1. Refactor Your Configuration

Start by refactoring the `dataProvider` and `entities` definitions from the `api.ts` file to a new file named `src/server/config.ts`. This allows you to use the same configurations for both your API and migrations.

In your `src/server/config.ts` file, define your entities and data provider as follows:

```ts
import { createPostgresDataProvider } from 'remult/postgres'
import { Task } from '../shared/task'

export const entities = [Task /* ...other entities */]
export const dataProvider = createPostgresDataProvider({
  connectionString: 'your connection string',
})
```

:::tip Using environment variables
In most cases, the connection string for your database will not be hard-coded but stored in an environment variable for security and flexibility. A common practice is to use a `.env` file to store environment variables in development and load them using the `dotenv` npm package. Here's how you can set it up:

1. Install the `dotenv` package:

   ```sh
   npm install dotenv
   ```

2. Create a `.env` file in the root of your project and add your database connection string:

   ```
   DATABASE_URL=your_connection_string
   ```

3. At the beginning of your `src/server/config.ts` file, load the environment variables:

   ```ts
   import { config } from 'dotenv'
   config()
   ```

4. Access the connection string using `process.env`:

   ```ts
   export const dataProvider = createPostgresDataProvider({
     connectionString: process.env['DATABASE_URL'],
   })
   ```

By following these steps, you ensure that your application securely and flexibly manages the database connection string.

:::

### 2. Adjust the API Configuration

Next, adjust your `api.ts` file to use the configurations from the `config.ts` file, and disable the `ensureSchema` migrations:

```ts
import { remultApi } from 'remult/remult-express'
import { dataProvider, entities } from './config'

export const api = remultApi({
  entities,
  dataProvider,
  ensureSchema: false,
})
```

### 3. Generate the migration

::: tip Prettier
The migration generator uses `prettier` to format the generated code for better readability and consistency. If you don't already have `prettier` installed in your project, we recommend installing it as a development dependency using the following command:

```sh
npm i -D prettier
```

:::

To enable automatic generation of migration scripts, follow these steps:

1. **Create the Migrations Folder:** In your `src/server` directory, create a new folder named `migrations`. This folder will hold all your migration scripts.

2. **Create the Migration Generator File:** Inside the `migrations` folder, create a file named `generate-migrations.ts`. This file will contain the script that generates migration scripts based on changes in your entities.

3. **Populate the Generator File:** Add the following code to `generate-migrations.ts`:

   ```ts
   import { generateMigrations } from 'remult/migrations'
   import { dataProvider, entities } from '../config'

   generateMigrations({
     dataProvider, // The data provider for your database
     entities, // Entity classes to include in the migration
     endConnection: true, // Close the database connection after generating migrations (useful for standalone scripts)
   })
   ```

   This script generates migration scripts based on changes in your entities. If you're calling this method on a server where the database connection should remain open, omit the `endConnection` parameter or set it to `false`.

4. **Generate Migrations:** To generate the migration scripts, run the `generate-migrations.ts` script using the following command:

   ```sh
   npx tsx src/server/migrations/generate-migrations.ts
   ```

   This command will create two important files:

   1. **`migrations-snapshot.json`**: This file stores the last known state of your entities. It helps the migration generator understand what changes have been made since the last migration was generated.
   2. **`migrations.ts`**: This file contains the actual migration scripts that need to be run to update your database schema. The structure of this file is as follows:

      ```ts
      import type { Migrations } from 'remult/migrations'

      export const migrations: Migrations = {
        0: async ({ sql }) => {
          await sql(`--sql
            CREATE SCHEMA IF NOT EXISTS public;
            CREATE TABLE "tasks" (
              "id" VARCHAR DEFAULT '' NOT NULL PRIMARY KEY,
              "title" VARCHAR DEFAULT '' NOT NULL
            )`)
        },
      }
      ```

      Each migration script is associated with a unique identifier (in this case, `0`) and contains the SQL commands necessary to update the database schema.

      By running this script whenever you make changes to your entities, you can automatically generate the necessary migration scripts to keep your database schema in sync with your application's data model.

      It's important to note that each migration can include any code that the developer wishes to include, not just SQL statements. The `sql` parameter is provided to facilitate running SQL commands, but you can also include other logic or code as needed. Additionally, developers are encouraged to add their own custom migrations to address specific requirements or changes that may not be covered by automatically generated migrations. This flexibility allows for a more tailored approach to managing database schema changes.

### 4. Run the Migrations

To apply the migrations to your database, you'll need to create a script that executes them.

#### Setting Up the Migration Script

1. **Create the Migration Script:** In the `src/server/migrations` folder, add a file named `migrate.ts`.

2. **Populate the Script:** Add the following code to `migrate.ts`:

   ```ts
   import { migrate } from 'remult/migrations'
   import { dataProvider } from '../config'
   import { migrations } from './migrations'

   migrate({
     dataProvider,
     migrations,
     endConnection: true, // Close the database connection after applying migrations
   })
   ```

   This script sets up the migration process. The `migrate` function checks the last migration executed on the database and runs all subsequent migrations based on their index in the `migrations` file. The entire call to `migrate` is executed in a transaction, ensuring that either all required migration steps are executed or none at all, maintaining the integrity of your database schema.

   ::: warning Warning: Database Transaction Support for Structural Changes
   It's important to note that some databases, like MySQL, do not support rolling back structural changes as part of a transaction. This means that if you make changes to the database schema (such as adding or dropping tables or columns) and something goes wrong, those changes might not be automatically rolled back. Developers need to be aware of this limitation and plan their migrations accordingly to avoid leaving the database in an inconsistent state.

   Always consult your database's documentation to understand the specifics of transaction support and plan your migrations accordingly.
   :::

3. **Execute the Script:** Run the migration script using the following command:

   ```sh
   npx tsx src/server/migrations/migrate.ts
   ```

## Integrating Migrations into Your Deployment Process

You have a couple of options for when and how to run your migrations:

- **As Part of the Build Step:** You can include the migration script as part of your build or deployment process. This way, if the migration fails, the deployment will also fail, preventing potential issues with an inconsistent database state.

- **During Application Initialization:** Alternatively, you can run the migrations when your application loads by using the `initApi` option in your `api.ts` file:

  ```ts
  // src/server/api.ts
  import { remultApi } from 'remult/remult-express'
  import { dataProvider, entities } from './config'
  import { migrate } from 'remult/migrations/migrate'
  import { migrations } from './migrations/migrations'
  import { remult } from 'remult'

  export const api = remultApi({
    entities,
    dataProvider,
    initApi: async () => {
      await migrate({
        dataProvider: remult.dataProvider,
        migrations,
        endConnection: false, //it's the default :)
      })
    },
  })
  ```

  This approach ensures that the migrations are applied each time the API initializes. Note that the `migrate` and `generateMigrations` functions typically close the connection used by the `dataProvider` when they complete. In this code, we disable this behavior using the `endConnection: false` option, instructing the `migrate` function to keep the `dataProvider` connection open when it completes.

Choose the approach that best fits your application's deployment and initialization process.

### Migration Philosophy: Embracing Backward Compatibility

We believe in designing migrations with a backward compatibility mindset. This approach ensures that older versions of the code can operate smoothly with newer versions of the database. To achieve this, we recommend:

- Never dropping columns or tables.
- Instead of altering a column, adding a new column and copying the data to it as part of the migration process.

This philosophy minimizes disruptions and ensures a smoother transition during database schema updates.



# Entities - Generate from Existing DB

# Generate Entities from Existing Database

## Remult kit

Want to use Remult for full-stack CRUD with your existing database?
Check out this video to see how to connect http://remult.dev to your existing database and start building type-safe #fullstack apps with any #typescript frontend, backend, and any DB!

Watch now 👉 https://youtu.be/5QCzJEO-qQ0.



# Entities - Offline Support

# Offline Support

In modern web applications, providing a seamless user experience often involves enabling offline functionality. This ensures that users can continue to interact with the application even without an active internet connection. Remult supports several offline databases that can be used to store data in the browser for offline scenarios, enhancing the application's resilience and usability.

## Using Local Database for Specific Calls

To utilize a local database for a specific call, you can pass the `dataProvider` as a second parameter to the `repo` function. This allows you to specify which database should be used for that particular operation.

```typescript
import { localDb } from './some-file.ts'

console.table(await repo(Task, localDb).find())
```

In this example, `localDb` is used as the data provider for the `Task` repository, enabling data fetching from the local database.

## JSON in LocalStorage / SessionStorage

For simple data storage needs, you can use JSON data providers that leverage the browser's `localStorage` or `sessionStorage`.

```typescript
import { JsonDataProvider, Remult } from 'remult'
export const remultLocalStorage = new Remult(new JsonDataProvider(localStorage))
```

This approach is straightforward and suitable for small datasets that need to persist across sessions or page reloads.

## JSON Storage in IndexedDB

For more complex offline storage needs, such as larger datasets and structured queries, `IndexedDB` provides a robust solution. Using Remult’s `JsonEntityIndexedDbStorage`, you can store entities in `IndexedDB`, which is supported across all major browsers. This allows for efficient offline data management while offering support for larger volumes of data compared to `localStorage` or `sessionStorage`.

```typescript
import { JsonDataProvider } from 'remult'
import { JsonEntityIndexedDbStorage } from 'remult'

// Initialize the JsonEntityIndexedDbStorage
const db = new JsonDataProvider(new JsonEntityIndexedDbStorage())

// Use the local IndexedDB to store and fetch tasks
console.table(await repo(Task, db).find())
```

In this example, `JsonEntityIndexedDbStorage` is used to persist the data to `IndexedDB`. This method is ideal for applications with large data sets or those requiring more complex interactions with the stored data in offline mode.

## JSON Storage in OPFS (Origin Private File System)

Origin Private File System (OPFS) is a modern browser feature supported by Chrome and Safari, allowing for more structured and efficient data storage in the frontend.

```typescript
import { JsonDataProvider } from 'remult'
import { JsonEntityOpfsStorage } from 'remult'

const localDb = new JsonDataProvider(new JsonEntityOpfsStorage())
```

Using OPFS with Remult's `JsonDataProvider` provides a robust solution for storing entities in the frontend, especially for applications requiring more complex data handling than what `localStorage` or `sessionStorage` can offer.

## `sql.js`: A SQLite Implementation for the Frontend

For applications requiring advanced database functionality, [`sql.js`](https://sql.js.org/) provides a SQLite implementation that runs entirely in the frontend. This allows you to use SQL queries and transactions, offering a powerful and flexible data management solution for offline scenarios.

Before using `sql.js` in your project, you need to install the package and its TypeScript definitions. Run the following commands in your terminal:

```bash
npm install sql.js
npm install @types/sql.js --save-dev
```

After installing the necessary packages, you can use the following code sample in your project:

```typescript
import { SqlDatabase } from 'remult'
import { SqlJsDataProvider } from 'remult/remult-sql-js'
import initSqlJs from 'sql.js'

let sqlDb: Database
// Initialize the SqlJsDataProvider with a new database instance
const sqlJsDataProvider = new SqlJsDataProvider(
  initSqlJs({
    locateFile: (file) => `https://sql.js.org/dist/${file}`, // for complete offline support, change this to a url that is available offline
  }).then((x) => {
    // Load the database from localStorage if it exists
    const dbData = localStorage.getItem('sqljs-db')
    if (dbData) {
      const buffer = new Uint8Array(JSON.parse(dbData))
      return (sqlDb = new x.Database(buffer))
    }
    return (sqlDb = new x.Database())
  }),
)

// Set up an afterMutation hook to save the database to localStorage after any mutation
sqlJsDataProvider.afterMutation = async () => {
  const db = sqlDb
  const buffer = db.export()

  localStorage.setItem('sqljs-db', JSON.stringify([...buffer]))
}
const localDb = new SqlDatabase(sqlJsDataProvider)
```

This code sets up a SQLite database using `sql.js` in your Remult project, with support for saving to and loading from `localStorage`.

## Summary

Remult's support for various offline databases empowers developers to create web applications that provide a seamless user experience, even in offline scenarios. Whether using simple JSON storage in `localStorage` or more advanced solutions like OPFS or `sql.js`, Remult offers the flexibility to choose the right data storage solution for your application's needs. By leveraging these offline capabilities, you can ensure that your application remains functional and responsive, regardless of the user's connectivity status.



# Entities - Active Record & EntityBase

# Mutability and the Active Record Pattern

The Active Record pattern is a concept in software architecture, particularly useful when working with mutable objects whose state may change over time. This design pattern facilitates direct interaction with the database through the object representing a row of the data table. In this article, we'll delve into the fundamentals of the Active Record pattern, contrasting it with immutable patterns, and exploring its implementation and advantages in software development.

### Immutable vs. Mutable Patterns

In modern software development, handling data objects can generally be approached in two ways: immutable and mutable patterns.

**Immutable objects** do not change once they are created. Any modification on an immutable object results in a new object. For example, in the React framework, immutability is often preferred:

```typescript
// Immutable update
const updatePerson = { ...person, name: 'newName' }
```

However, libraries like MobX offer the flexibility to work with mutable objects while still providing the reactivity that React components need.

**Mutable objects**, on the other hand, allow for changes directly on the object itself:

```typescript
// Mutable update
person.name = 'newName'
```

Mutable patterns are especially prevalent in scenarios where the state of objects changes frequently, making them a staple in many programming environments outside of React.

### The Role of Active Record Pattern

The Active Record pattern embodies the concept of mutability by binding business logic to object data models. Typically, each model instance corresponds to a row in the database, with the class methods providing the functionality to create, read, update, and delete records.

### Warning: Mutable Objects in React

Using mutable objects with the Active Record pattern in React (without libraries like MobX) requires careful handling. React’s rendering cycle is built around the premise of immutability; it typically relies on immutable state management to trigger re-renders. When mutable objects change state outside the scope of React's `useState` or `useReducer`, React does not automatically know to re-render the affected components. This can lead to issues where the UI does not reflect the current application state.

These challenges can be mitigated by integrating state management tools that are designed to work well with mutable objects, such as MobX. MobX provides mechanisms to track changes in data and automatically re-render components when mutations occur. This aligns more naturally with the Active Record pattern within the context of React, ensuring that the UI stays in sync with the underlying data.

#### Using EntityBase and IdEntity

In practice, leveraging the Active Record pattern often involves inheriting from classes such as `EntityBase` or `IdEntity` (a variant of `EntityBase` with a UUID as the identifier). These base classes enrich models with methods that simplify manipulations of their attributes and their persistence in the database.

```typescript
@Entity('people')
export class Person extends IdEntity {
  @Fields.string()
  name = ''
}
```

**Explanation:**
The `Person` class represents individuals in the 'people' table and inherits from `IdEntity`. This inheritance means that there is no need to explicitly define an `id` field for this class, as `IdEntity` automatically includes a UUID field (`id`). Consequently, `Person` benefits from all the functionalities of `EntityBase`, which include tracking changes and handling CRUD operations, while also automatically gaining a UUID as the identifier.

### Mutable vs EntityBase (active-record)

**Traditional approach without Active Record:**

```typescript
// Updating a person's name the traditional way
await repo(Person).update(person, { name: 'newName' })
```

**Using Active Record with EntityBase:**

```typescript
// Active Record style
person.name = 'newName'
await person.save()
```

This pattern also simplifies other operations:

```typescript
// Deleting a record
await person.delete()

// Checking if the record is new
if (person.isNew()) {
  // Perform a specific action
}
```

#### Helper Members in EntityBase

EntityBase provides additional utility members like `_` and `$` to facilitate more complex interactions:

- **`_` (EntityRef Object):** Allows performing operations on a specific instance of an entity.

```typescript
await person._.reload()
```

- **`$` (FieldsRef):** Provides access to detailed information about each field in the current instance, such as their original and current values:

```typescript
// Logging changes in a field
console.log(
  `Name changed from "${person.$.name.originalValue}" to "${person.name}"`,
)
```

### Alternative Implementations

Even without direct inheritance from `EntityBase`, similar functionalities can be achieved using helper functions such as `getEntityRef`, which encapsulates an entity instance for manipulation and persistence:

```typescript
const ref = getEntityRef(person)
await ref.save()
```

### Conclusion

The Active Record pattern offers a straightforward and intuitive approach to interacting with database records through object-oriented models. It is particularly beneficial in environments where business logic needs to be tightly coupled with data manipulation, providing a clear and efficient way to handle data state changes. However, integrating the Active Record pattern with mutable objects in React can be challenging.



# Active Record & EntityBase - Entity Backend Methods

# Entity Instance Backend Methods

When leveraging the Active Record pattern, backend methods for entity instances offer a powerful way to integrate client-side behavior with server-side logic. These methods, when invoked, transport the entire entity's state from the client to the server and vice versa, even if the data has not yet been saved. This feature is particularly useful for executing entity-specific operations that require a round-trip to the server to maintain consistency and integrity.

## Overview of Entity Backend Methods

Entity backend methods enable all the fields of an entity, including unsaved values, to be sent to and from the server during the method's execution. This approach is essential for operations that rely on the most current state of an entity, whether or not the changes have been persisted to the database.

### Defining a Backend Method

To define a backend method, use the `@BackendMethod` decorator to annotate methods within an entity class. This decorator ensures that the method is executed on the server, taking advantage of server-side resources and permissions.

Here is an example demonstrating how to define and use a backend method in an entity class:

```typescript
@Entity('tasks', {
  allowApiCrud: true,
})
export class Task extends IdEntity {
  @Fields.string()
  title = ''

  @Fields.boolean()
  completed = false

  @BackendMethod({ allowed: true })
  async toggleCompleted() {
    this.completed = !this.completed
    console.log({
      title: this.title,
      titleOriginalValue: this.$.title.originalValue,
    })
    await this.save()
  }
}
```

### Calling the Backend Method from the Frontend

Once the backend method is defined, it can be called from the client-side code. This process typically involves fetching an entity instance and then invoking the backend method as shown below:

```typescript
const task = await repo(Task).findFirst()
await task.toggleCompleted()
```

### Security Considerations

::: danger
It's important to note that backend methods bypass certain API restrictions that might be set on the entity, such as `allowApiUpdate=false`. This means that even if an entity is configured not to allow updates through standard API operations, it can still be modified through backend methods if they are permitted by their `allowed` setting. Consequently, developers must explicitly handle security and validation within these methods to prevent unauthorized actions.

The principle here is that if a user has permission to execute the `BackendMethod`, then all operations within that method are considered authorized. It is up to the developer to implement any necessary restrictions within the method itself.
:::



# Active Record & EntityBase - Mutable Controllers

# Introduction to Mutable Controllers and Backend Methods

In web development architectures, mutable controllers offer a convenient way to manage state and facilitate interactions between the client (frontend) and the server (backend). These controllers are useful in scenarios where state needs to be maintained and manipulated across server calls, providing a streamlined approach to handling data.

## Overview of Controller Backend Methods

A Controller is a class designed to encapsulate business logic and data processing. When a backend method in a controller is called, it ensures that all field values are preserved and appropriately transferred between the frontend and backend, maintaining state throughout the process.

### Defining a Mutable Controller

The mutable controller is typically defined in a shared module, allowing both the frontend and backend to interact with it efficiently. Below is an example of how to define such a controller and a backend method within it.

### Explanation with Data Flow and Example Usage

This example demonstrates the use of a mutable controller, `UserSignInController`, to handle the sign-in process for users in a web application. Let's break down the key components of this example:

1. **Controller Definition**: The `UserSignInController` is a class annotated with `@Controller('UserSignInController')`, indicating that it serves as a controller for handling user sign-in operations.

2. **Data Flow**: When the `signInUser` backend method is called from the frontend, all the values of the controller fields (`email`, `password`, `rememberMe`) will be sent to the backend for processing. Once the method completes its execution, the updated values (if any) will be sent back to the frontend.

### Example Usage

Here's how you can use the `UserSignInController` on the frontend to initiate the sign-in process:

```typescript
const signInController = new UserSignInController()
signInController.email = 'user@example.com'
signInController.password = 'password123'
signInController.rememberMe = true // Optional: Set to true if the user wants to remain logged in

try {
  const user = await signInController.signInUser()
  console.log(`User signed in: ${user.email}`)
} catch (error) {
  console.error('Sign-in failed:', error.message)
}
```

In this example, we create an instance of `UserSignInController` and set its `email`, `password`, and `rememberMe` fields with the appropriate values. We then call the `signInUser` method to initiate the sign-in process. If successful, we log a message indicating that the user has signed in. If an error occurs during the sign-in process, we catch the error and log a corresponding error message.

This usage demonstrates how to interact with the mutable controller to handle user sign-in operations seamlessly within a web application.

### Summary

Mutable controllers and backend methods provide a powerful mechanism for managing state and handling user interactions in web applications. By encapsulating business logic and data processing within controllers, developers can ensure consistent behavior and efficient data flow between the frontend and backend. With the ability to preserve and transfer field values during server calls, mutable controllers facilitate a smooth and responsive user experience, enhancing the overall functionality and performance of web applications.



# Stacks

<script setup>
  import Icon from '../../components/Icon.vue'
</script>

# Stacks

## Frameworks

<div style="display: grid; grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); gap: 5rem; margin-top: 2rem">
	<Icon tech="react" sizeIco=100 link="/docs/installation/framework/react" />
	<Icon tech="angular" sizeIco=100 link="/docs/installation/framework/angular" />
	<Icon tech="vue" sizeIco=100 link="/docs/installation/framework/vue" />
	<Icon tech="svelte" sizeIco=100 link="/docs/installation/framework/sveltekit" />
	<Icon tech="nextjs" sizeIco=100 link="/docs/installation/framework/nextjs" />
	<Icon tech="solid" sizeIco=100 link="/docs/installation/framework/solid" />
	<Icon tech="nuxt" sizeIco=100 link="/docs/installation/framework/nuxt" />
</div>

## Servers

<div style="display: grid; grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); gap: 5rem; margin-top: 2rem">
	<Icon tech="express" sizeIco=100 link="/docs/installation/server/express" />
	<Icon tech="fastify" sizeIco=100 link="/docs/installation/server/fastify" />
	<Icon tech="hono" sizeIco=100 link="/docs/installation/server/hono" />
	<Icon tech="hapi" sizeIco=100 link="/docs/installation/server/hapi" />
	<Icon tech="koa" sizeIco=100 link="/docs/installation/server/koa" />
	<Icon tech="nest" sizeIco=100 link="/docs/installation/server/nest" />
</div>

## Databases

<div style="display: grid; grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); gap: 5rem; margin-top: 2rem">
	<Icon tech="postgres" sizeIco=100 link="/docs/installation/database/postgresql" />
	<Icon tech="mysql" sizeIco=100 link="/docs/installation/database/mysql" />
	<Icon tech="mongodb" sizeIco=100 link="/docs/installation/database/mongodb" />
	<Icon tech="sqlite" sizeIco=100 link="/docs/installation/database/better-sqlite3" />
	<Icon tech="sqljs" sizeIco=100 link="/docs/installation/database/sqljs" />
	<Icon tech="mssql" sizeIco=100 link="/docs/installation/database/mssql" />
	<Icon tech="bun-sqlite" sizeIco=100 link="/docs/installation/database/bun-sqlite" />
	<Icon tech="turso" sizeIco=100 link="/docs/installation/database/turso" />
	<Icon tech="duckdb" sizeIco=100 link="/docs/installation/database/duckdb" />
	<Icon tech="oracle" sizeIco=100 link="/docs/installation/database/oracle" />
	<Icon tech="d1" sizeIco=100 link="/docs/installation/database/d1" />
	<Icon tech="json files" sizeIco=100 link="/docs/installation/database/json" />
</div>



# Stacks - Framework

<script setup>
  import Icon from '../../../components/Icon.vue'
</script>

# Select a framework

<div style="display: grid; grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); gap: 5rem; margin-top: 2rem">
	<Icon tech="react" sizeIco=100 link="/docs/installation/framework/react" />
	<Icon tech="angular" sizeIco=100 link="/docs/installation/framework/angular" />
	<Icon tech="vue" sizeIco=100 link="/docs/installation/framework/vue" />
	<Icon tech="svelte" sizeIco=100 link="/docs/installation/framework/sveltekit" />
	<Icon tech="nextjs" sizeIco=100 link="/docs/installation/framework/nextjs" />
	<Icon tech="solid" sizeIco=100 link="/docs/installation/framework/solid" />
	<Icon tech="nuxt" sizeIco=100 link="/docs/installation/framework/nuxt" />
</div>



# Framework - React

# React

## Create a React Project with Vite

To set up a new React project using Vite, run the following commands:

```sh
npm create vite@latest remult-react-project -- --template react-ts
cd remult-react-project
```

## Install Remult

Install the latest version of Remult:

```bash
npm install remult@latest
```

## Enable TypeScript Decorators in Vite

To enable the use of decorators in your React app, modify the `vite.config.ts` file by adding the following to the `defineConfig` section:

```ts{6-12}
// vite.config.ts

// ...
export default defineConfig({
  plugins: [react()],
  esbuild: {
    tsconfigRaw: {
      compilerOptions: {
        experimentalDecorators: true,
      },
    },
  },
});
```

This configuration ensures that TypeScript decorators are enabled for the project.

## Proxy API Requests from Vite DevServer to the API Server

In development, your React app will be served from `http://localhost:5173`, while the API server will run on `http://localhost:3002`. To allow the React app to communicate with the API server during development, use Vite's [proxy](https://vitejs.dev/config/#server-proxy) feature.

Add the following proxy configuration to the `vite.config.ts` file:

```ts{6}
// vite.config.ts

//...
export default defineConfig({
  plugins: [react()],
  server: { proxy: { "/api": "http://localhost:3002" } },
  esbuild: {
    tsconfigRaw: {
      compilerOptions: {
        experimentalDecorators: true,
      },
    },
  },
});
```

This setup proxies all requests starting with `/api` from `http://localhost:5173` to your API server running at `http://localhost:3002`.

## Configure a Server

Now that the app is set up, [Select an API Server](../server/)



# Framework - Angular

# Angular

## Create an Angular Project

To set up a new Angular project, use the Angular CLI:

```sh
ng new remult-angular
cd remult-angular
```

## Install Remult

Install the latest version of Remult in your Angular project:

```bash
npm install remult@latest
```

## Proxy API Requests from Angular DevServer to the API Server

In development, your Angular app will be served from `http://localhost:4200`, while the API server will run on `http://localhost:3002`. To allow the Angular app to communicate with the API server during development, you can use Angular's [proxy](https://angular.io/guide/build#proxying-to-a-backend-server) feature.

1. Create a file named `proxy.conf.json` in the root folder of your project with the following content:

```json
// proxy.conf.json

{
  "/api": {
    "target": "http://localhost:3002",
    "secure": false
  }
}
```

This configuration redirects all API calls from the Angular dev server to the API server running at `http://localhost:3002`.

## Adjust the `package.json`

Modify the `package.json` to use the newly created proxy configuration when serving the Angular app:

```json
// package.json

"dev": "ng serve --proxy-config proxy.conf.json --open",
```

Running the `dev` script will start the Angular dev server with the proxy configuration enabled.

## Configure a Server

Now that the app is set up, [Select an API Server](../server/)



# Framework - Vue

# Vue

## Create a Vue Project with Vite

To set up a new Vue project using Vite, run the following commands:

```sh
npm init -y vue@latest
cd remult-vue-project
```

## Install Remult

Install the latest version of Remult:

```bash
npm install remult@latest
```

## Enable TypeScript Decorators in Vite

To enable the use of decorators in your React app, modify the `vite.config.ts` file by adding the following to the `defineConfig` section:

```ts{6-12}
// vite.config.ts

// ...
export default defineConfig({
  plugins: [vue()],
  esbuild: {
    tsconfigRaw: {
      compilerOptions: {
        experimentalDecorators: true,
      },
    },
  },
});
```

This configuration ensures that TypeScript decorators are enabled for the project.

## Proxy API Requests from Vite DevServer to the API Server

In development, your React app will be served from `http://localhost:5173`, while the API server will run on `http://localhost:3002`. To allow the React app to communicate with the API server during development, use Vite's [proxy](https://vitejs.dev/config/#server-proxy) feature.

Add the following proxy configuration to the `vite.config.ts` file:

```ts{6}
// vite.config.ts

//...
export default defineConfig({
  plugins: [vue()],
  server: { proxy: { "/api": "http://localhost:3002" } },
  esbuild: {
    tsconfigRaw: {
      compilerOptions: {
        experimentalDecorators: true,
      },
    },
  },
});
```

This setup proxies all requests starting with `/api` from `http://localhost:5173` to your API server running at `http://localhost:3002`.

## Configure a Server

Now that the app is set up, [Select an API Server](../server/)



# Framework - Sveltekit

# SvelteKit

## Create a SvelteKit Project

To create a new SvelteKit project, run the following command:

```sh
npx sv@latest create remult-sveltekit-todo
```

During the setup, answer the prompts as follows:

1. **Which Svelte app template?**: ... `minimal` Project
2. **Add type checking with TypeScript?** ... Yes, using `TypeScript` syntax
3. **Select additional options**: ... We didn't select anything for this tutorial. Feel free to adapt it to your needs.
4. **Which package manager?**: ... We took `npm`, if you perfer others, feel free.

Once the setup is complete, navigate into the project directory:

```sh
cd remult-sveltekit-todo
```

## Install Required Packages and Remult

Install Remult and any necessary dependencies by running:

```sh
npm install remult --save-dev
```

## Bootstrap Remult

To set up Remult in your SvelteKit project:

1. Create your remult `api`

::: code-group

```ts [src/server/api.ts]
import { remultApi } from 'remult/remult-sveltekit'

export const api = remultApi({})
```

:::

2. Create a remult `api route`

::: code-group

```ts [src/routes/api/[...remult]/+server.ts]
import { api } from '../../../server/api'

export const { GET, POST, PUT, DELETE } = api
```

:::

## Final Tweaks

Remult uses TypeScript decorators to enhance classes into entities. To enable decorators in your SvelteKit project, modify the `tsconfig.json` file by adding the following to the `compilerOptions` section:

```json [tsconfig.json]
{
  "compilerOptions": {
    "experimentalDecorators": true // [!code ++]
  }
}
```

## Run the App

To start the development server, run the following command:

```sh
npm run dev
```

Your SvelteKit app will be available at [http://localhost:5173](http://localhost:5173).

Your SvelteKit project with Remult is now up and running.

# Extra

## Extra - Remult in other SvelteKit routes

To enable remult across all sveltekit route

::: code-group

```ts [src/hooks.server.ts]
import { sequence } from '@sveltejs/kit/hooks'
import { api as handleRemult } from './server/api'

export const handle = sequence(
  // Manage your sequence of handlers here
  handleRemult,
)
```

:::

## Extra - Universal load & SSR

To Use remult in ssr `PageLoad` - this will leverage the `event`'s fetch to load data on the server
without reloading it on the frontend, and abiding to all api rules even when it runs on the server

::: code-group

```ts [src/routes/+page.ts]
import { remult } from 'remult'
import type { PageLoad } from './$types'

export const load = (async (event) => {
  // Instruct remult to use the special svelte fetch
  // Like this univeral load will work in SSR & CSR
  remult.useFetch(event.fetch)
  return repo(Task).find()
}) satisfies PageLoad
```

:::

::: tip
You can add this in `+layout.ts` as well and all routes **under** will have the correct fetch out of the box.
:::

## Extra - Server load

If you return a remult entity from the `load` function of a `+page.server.ts`,
SvelteKit will complain and show this error:

```bash
Error: Data returned from `load` while rendering / is not serializable:
Cannot stringify arbitrary non-POJOs (data.tasks[0])
```

To fix this, you can use `repo(Entity).toJson()` in the server load function and `repo(Entity).fromJson()` in the .svelte file
to serialize and deserialize well the entity.

::: code-group

```ts [src/routes/+page.server.ts]
import { repo } from 'remult'
import type { PageServerLoad } from './$types'
import { Task } from '../demo/todo/Task'

export const load = (async () => {
  const tasks = repo(Task).toJson(await repo(Task).find())
  return {
    tasks,
  }
}) satisfies PageServerLoad
```

```svelte [src/routes/+page.svelte]
<script lang="ts">
  import type { PageData } from "./$types";
  import { Task } from "../demo/todo/Task";
  import { repo } from "remult";

  let { data }: { data: PageData } = $props();

  let tasks = repo(Task).fromJson(data.tasks);
</script>
```

:::

---

#### Since `@sveltejs/kit@2.11.0`, there is a new feature: [Universal-hooks-transport](https://svelte.dev/docs/kit/hooks#Universal-hooks-transport)

With this new feature, you can get rid of `repo(Entity).toJson()` and `repo(Entity).fromJson()` thanks to this file: `hooks.ts`.

::: code-group

```ts [src/hooks.ts]
import { repo, type ClassType } from 'remult'
import { Task } from './demo/todo/Task'
import type { Transport } from '@sveltejs/kit'
import { api } from './server/api'

// You can have:
// A/ a local entity array to work only these ones (like here)
//  or
// B/ import a global entity array that will be
//    shared between backend and frontend (not in ./server/api.ts)
const entities = [Task]

export const transport: Transport = {
  remultTransport: {
    encode: (value: any) => {
      for (let index = 0; index < entities.length; index++) {
        const element = entities[index] as ClassType<any>
        if (value instanceof element) {
          return {
            ...repo(element).toJson(value),
            entity_key: repo(element).metadata.key,
          }
        }
      }
    },
    decode: (value: any) => {
      for (let index = 0; index < entities.length; index++) {
        const element = entities[index] as ClassType<any>
        if (value.entity_key === repo(element).metadata.key) {
          return repo(element).fromJson(value)
        }
      }
    },
  },
}
```

```ts [src/routes/+page.server.ts]
import { repo } from 'remult'
import type { PageServerLoad } from './$types'
import { Task } from '../demo/todo/Task'

export const load = (async () => {
  // const tasks = repo(Task).toJson(await repo(Task).find()) // [!code --]
  const tasks = await repo(Task).find()
  return {
    tasks,
  }
}) satisfies PageServerLoad
```

```svelte [src/routes/+page.svelte]
<script lang="ts">
  import type { PageData } from "./$types";
  import { repo } from "remult";

  let { data }: { data: PageData } = $props();

  // let tasks = repo(Task).fromJson(data.tasks) // [!code --]
  let tasks = data.tasks
</script>
```

:::

## Extra - Svelte 5 & Reactivity

Remult is fully compatible with Svelte 5, Rune, and Reactivity.

To take full advantage of it, add this snippet:

::: code-group

```html [src/routes/+layout.svelte]
<script lang="ts">
  import { remult, Remult } from 'remult'
  import { createSubscriber } from 'svelte/reactivity'

  // To be done once in the application.
  function initRemultSvelteReactivity() {
    // Auth reactivity (remult.user, remult.authenticated(), ...)
    {
      let update = () => {}
      let s = createSubscriber((u) => {
        update = u
      })
      remult.subscribeAuth({
        reportObserved: () => s(),
        reportChanged: () => update(),
      })
    }

    // Entities reactivity
    {
      Remult.entityRefInit = (x) => {
        let update = () => {}
        let s = createSubscriber((u) => {
          update = u
        })
        x.subscribe({
          reportObserved: () => s(),
          reportChanged: () => update(),
        })
      }
    }
  }
  initRemultSvelteReactivity()
</script>
```

:::

Then you can use `$state`, `$derived` like any other places

::: code-group

```html [src/routes/+page.svelte]
<script lang="ts">
  // Prepare a new task
  let editingTask = $state(repo(Task).create())

  // Check if the form has empty fields
  let formHasEmpty = $derived(!editingTask || editingTask.title.length === 0)

  // Clone the task to edit
  const editTask = async (task: Task) => {
    editingTask = repo(Task).getEntityRef(task).clone()
  }
</script>
```

:::

### Focus on auth reactivity

Anywhere in your frontend code you can set `remult.user = xxx` and all remult auth reactivity will work (remult.user, remult.authenticated(), ...)

```ts
const logout = async () => {
  try {
    remult.user = await AuthController.signOut()
  } catch (error) {
    alert(error.message)
  }
}
```

If you want `remult.user` to be filled in SSR, here is the code:

::: code-group

```svelte [src/routes/+layout.svelte]
<script lang="ts">
  import { untrack } from 'svelte'
  import type { LayoutData } from './$types'

  interface Props {
    data: LayoutData
    children?: import('svelte').Snippet
  }

  let { data, children }: Props = $props()

  $effect(() => {
    // Trigger the effect only on data.user update
    data.user
    untrack(() => {
      remult.user = data.user
    })
  })

  // initRemultSvelteReactivity stuff
</script>

{@render children?.()}
```

```ts [src/routes/+layout.server.ts]
import { remult } from 'remult'

import type { LayoutServerLoad } from './$types'

export const load = (async () => {
  return { user: remult.user }
}) satisfies LayoutServerLoad
```

:::

And you can trigger this with :

```ts
import { invalidateAll } from '$app/navigation'

const logout = async () => {
  try {
    await AuthController.signOut()
    invalidateAll() // [!code ++] // This will trigger the layout.server.ts load function
  } catch (error) {
    alert(error.message)
  }
}
```

## Extra - Remote Functions

SvelteKit is introducing a new feature called [Remote Functions](https://svelte.dev/docs/kit/remote-functions). It's early, but we want to see how it integrates with Remult.

Here is the default doc example (zod & drizzle or valibot & prisma, ...):

```ts
import { error } from '@sveltejs/kit'
import { query } from '$app/server'
import * as v from 'valibot' // or zod, ... any standard schema library
import * as db from '$lib/server/database' // with drizzle, prisma, pg, ... any database library

export const getPost = query(
  z.string(), // Standard Schema
  async (slug) => {
    const [post] = await db.sql`SELECT * FROM post WHERE slug = ${slug}`
    if (!post) error(404, 'Not found')
    return post
  },
)
```

With remult library, you have both:

- the database layer
- the standard schema layer

So you can replace the previous code with this:

```ts
import { error } from '@sveltejs/kit'
import { query } from '$app/server'
import { standardSchema, repo } from 'remult'
import { Post } from '$lib/entities'

export const getPost = query(
  standardSchema(repo(Post), 'slug'), // Standard Schema
  async ({ slug }) => {
    const post = await repo(Post).findFirst({ slug })
    if (!post) error(404, 'Not found')
    return post
  },
)
```

We are excited to see how you will use it 🚀

::: tip
More info about [remult standard schema](/docs/standard-schema)
:::



# Framework - Next.js

# Next.js

## Create a Next.js Project

To create a new Next.js project, run the following command:

```sh
npx -y create-next-app@latest remult-nextjs
```

When prompted, use these answers:

```sh
✔ Would you like to use TypeScript? ... Yes
✔ Would you like to use ESLint? ... No
✔ Would you like to use Tailwind CSS? ... No
✔ Would you like to use `src/` directory? ... Yes
✔ Would you like to use App Router? (recommended) ... Yes
✔ Would you like to customize the default import alias? ... No
```

Afterward, navigate into the newly created project folder:

```sh
cd remult-nextjs
```

## Install Remult

Install the latest version of Remult:

```bash
npm install remult
```

## Bootstrap Remult in the Backend

Remult is bootstrapped in a Next.js app by creating a [catch-all dynamic API route](https://nextjs.org/docs/app/building-your-application/routing/dynamic-routes#catch-all-segments). This route will pass API requests to an object created using the `remultApi` function.

1. **Create an API file**

   In the `src/` directory, create a file called `api.ts` with the following code to set up Remult:

   ```ts
   // src/api.ts

   import { remultApi } from 'remult/remult-next'

   export const api = remultApi({})
   ```

2. **Create the API Route**

   In the `src/app/api` directory, create a `[...remult]` subdirectory. Inside that directory, create a `route.ts` file with the following code:

   ```ts
   // src/app/api/[...remult]/route.ts

   import { api } from '../../../api'

   export const { POST, PUT, DELETE, GET } = api
   ```

This file serves as a catch-all route for the Next.js API, handling all API requests by routing them through Remult.

## Enable TypeScript Decorators

To enable the use of decorators in your Next.js app, modify the `tsconfig.json` file. Add the following entry under the `compilerOptions` section:

```json{7}
// tsconfig.json

{
  ...
  "compilerOptions": {
    ...
    "experimentalDecorators": true // add this line
    ...
  }
}
```

## Run the App

To start the development server, open a terminal and run the following command:

```sh
npm run dev
```

Your Next.js app is now running with Remult integrated and listening for API requests.



# Framework - SolidStart

# SolidStart

### Step 1: Create a New SolidStart Project

Run the following command to initialize a new SolidStart project:

```sh
npm init solid@latest remult-solid-start
```

Answer the prompts as follows:

```sh
o  Is this a Solid-Start project?   Yes
o  Which template would you like to use?   basic
o  Use TypeScript?   Yes
```

Once completed, navigate to the project directory:

```sh
cd remult-solid-start
```

### Step 2: Install Remult

To install the Remult package, run:

```sh
npm i remult
```

### Step 3: Bootstrap Remult in the Backend

Remult is integrated into `SolidStart` using a [catch-all dynamic API route](https://start.solidjs.com/core-concepts/routing#catch-all-routes), which passes API requests to a handler created using the `remultApi` function.

1. **Create the Remult API Configuration File**

   In the `src` directory, create a file named `api.ts` with the following code:

   ```ts
   // src/api.ts

   import { remultApi } from 'remult/remult-solid-start'

   export const api = remultApi({})
   ```

2. **Set Up the Catch-All API Route**

   In the `src/routes/api/` directory, create a file named `[...remult].ts` with the following code:

   ```ts
   // src/routes/api/[...remult].ts

   import { api } from '../../api.js'

   export const { POST, PUT, DELETE, GET } = api
   ```

### Step 4: Enable TypeScript Decorators

1. **Install Babel Plugins for Decorators**:

   ```sh
   npm i -D @babel/plugin-proposal-decorators @babel/plugin-transform-class-properties
   ```

2. **Configure Babel Plugins in SolidStart**:

   Add the following configuration to the `app.config.ts` file to enable TypeScript decorators:

   ```ts{6-14}
   // app.config.ts

   import { defineConfig } from "@solidjs/start/config"

   export default defineConfig({
     //@ts-ignore
     solid: {
       babel: {
         plugins: [
           ["@babel/plugin-proposal-decorators", { version: "legacy" }],
           ["@babel/plugin-transform-class-properties"],
         ],
       },
     },
   })
   ```

### Setup Complete

Your SolidStart project is now set up with Remult and ready to run. You can now proceed to the next steps of building your application.



# Framework - Nuxt

### Create a Nuxt Project

To create a new Nuxt project, run the following command:

```sh
npx nuxi init remult-nuxt-todo
cd remult-nuxt-todo
```

### Install Remult

Install Remult in your Nuxt project by running the following command:

```sh
npm install remult
```

### Enable TypeScript Decorators

To enable the use of TypeScript decorators in your Nuxt project, modify the `nuxt.config.ts` file as follows:

```ts [nuxt.config.ts]
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
  compatibilityDate: '2024-04-03',
  devtools: { enabled: true },
  nitro: {
    esbuild: {
      options: {
        tsconfigRaw: {
          compilerOptions: {
            experimentalDecorators: true,
          },
        },
      },
    },
  },
  vite: {
    esbuild: {
      tsconfigRaw: {
        compilerOptions: {
          experimentalDecorators: true,
        },
      },
    },
  },
})
```

### Bootstrap Remult

1. **Create the API File**

   In the `server/api/` directory, create a dynamic API route that integrates Remult with Nuxt. The following code sets up the API and defines the entities to be used:

   ```ts [server/api/[...remult].ts]
   import { remultApi } from 'remult/remult-nuxt'
   import { Task } from '../../demo/todo/Task.js'

   export const api = remultApi({
     admin: true,
     entities: [Task],
   })

   export default defineEventHandler(api)
   ```

   This setup uses the Remult `Task` entity and registers the API routes dynamically for the entities within the app.

### Run the App

To start the development server, run:

```sh
npm run dev
```

The Nuxt app will now be running on the default address [http://localhost:3000](http://localhost:3000).

### Setup Completed

Your Nuxt app with Remult is now set up and ready to go. You can now move on to defining your entities and building your task list app.



# Stacks - Server

<script setup>
  import Icon from '../../../components/Icon.vue'
</script>

# Select a server

<div style="display: grid; grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); gap: 5rem; margin-top: 2rem">
	<Icon tech="express" sizeIco=100 link="/docs/installation/server/express" />
	<Icon tech="fastify" sizeIco=100 link="/docs/installation/server/fastify" />
	<Icon tech="hono" sizeIco=100 link="/docs/installation/server/hono" />
	<Icon tech="elysia" sizeIco=100 link="/docs/installation/server/elysia" />
	<Icon tech="hapi" sizeIco=100 link="/docs/installation/server/hapi" />
	<Icon tech="koa" sizeIco=100 link="/docs/installation/server/koa" />
	<Icon tech="nest" sizeIco=100 link="/docs/installation/server/nest" />
</div>



# Server - Express

# Express

### Install Required Packages

To set up your Express server with Remult, run the following commands to install the necessary packages:

```sh
npm install express remult
npm install --save-dev @types/express tsx
```

### Bootstrap Remult in the Backend

Remult is integrated into your backend as an `Express middleware`.

1. **Create the API File**

   Create a new `api.ts` file in the `src/server/` folder with the following code to set up the Remult middleware:

   ```ts
   // src/server/api.ts

   import { remultApi } from 'remult/remult-express'

   export const api = remultApi({})
   ```

2. **Register the Middleware**

   Update the `index.ts` file in your `src/server/` folder to include the Remult middleware. Add the following lines:

   ```ts{4,7}
   // src/server/index.ts

   import express from "express"
   import { api } from "./api.js"

   const app = express()
   app.use(api)

   app.listen(3002, () => console.log("Server started"))
   ```

   ::: warning ESM Configuration
   In this tutorial, we are using ECMAScript modules (`esm`) for the Node.js server. This means that when importing files, you must include the `.js` suffix (as shown in the `import { api } from "./api.js"` statement).

   Additionally, make sure to set `"type": "module"` in your `package.json` file.
   :::

#### Create the Server's TypeScript Configuration

In the root folder, create a TypeScript configuration file named `tsconfig.server.json` to manage the server's settings:

```json
{
  "compilerOptions": {
    "experimentalDecorators": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "outDir": "dist",
    "rootDir": "src",
    "module": "nodenext"
  },
  "include": ["src/server/**/*", "src/shared/**/*"]
}
```

This configuration enables TypeScript decorators, ensures compatibility with ECMAScript modules, and specifies the file paths for the server and shared code.

#### Create an `npm` Script to Start the API Server

To simplify the development process, add a new script in your `package.json` file to start the Express server in development mode:

```json
// package.json

"dev-node": "tsx watch --env-file=.env --tsconfig tsconfig.server.json src/server"
```

- `tsx`: A TypeScript Node.js execution environment that watches for file changes and automatically restarts the server on each save.
- `--env-file=.env`: Ensures environment variables are loaded from the `.env` file.
- `--tsconfig tsconfig.server.json`: Specifies the TypeScript configuration file for the server.

#### Start the Node Server

Finally, open a new terminal and run the following command to start the development server:

```sh
npm run dev-node
```

The server will now run on port 3002. `tsx` will watch for any file changes, automatically restarting the server whenever updates are made.



# Server - Fastify

# Fastify

### Install Required Packages

To set up your Fastify server with Remult, run the following commands to install the necessary packages:

```sh
npm install fastify remult
npm install --save-dev tsx
```

### Bootstrap Remult in the Backend

Remult is integrated into your backend as Fastify middleware.

1. **Create the API File**

   Create a new `api.ts` file in the `src/server/` folder with the following code to set up the Remult middleware for Fastify:

   ```ts
   // src/server/api.ts

   import { remultApi } from 'remult/remult-fastify'

   export const api = remultApi({})
   ```

2. **Register the Middleware**

   Update the `index.ts` file in your `src/server/` folder to include the Remult middleware. Add the following lines:

   ```ts{5,9}
   // src/server/index.ts

   import fastify from "fastify"
   import { api } from "./api.js"

   const app = Fastify();

   app.register(api);

   app.listen({ port: 3002 }, () => console.log("Server started"))
   ```

   ::: warning ESM Configuration
   Similar to the Express setup, when using ECMAScript modules (`esm`) in Fastify, you must include the `.js` suffix when importing files (as shown in the `import { api } from "./api.js"` statement).

   Also, ensure that `"type": "module"` is set in your `package.json`.
   :::

#### Create the Server's TypeScript Configuration

In the root folder, create a TypeScript configuration file named `tsconfig.server.json` for the server project:

```json
{
  "compilerOptions": {
    "experimentalDecorators": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "outDir": "dist",
    "rootDir": "src",
    "module": "nodenext"
  },
  "include": ["src/server/**/*", "src/shared/**/*"]
}
```

This configuration enables TypeScript decorators, ensures compatibility with ECMAScript modules, and specifies the file paths for the server and shared code.

#### Create an `npm` Script to Start the API Server

To simplify the development process, add a new script in your `package.json` to start the Fastify server in development mode:

```json
// package.json

"dev-node": "tsx watch --env-file=.env --tsconfig tsconfig.server.json src/server"
```

- `tsx`: A TypeScript Node.js execution environment that watches for file changes and automatically restarts the server on each save.
- `--env-file=.env`: Ensures environment variables are loaded from the `.env` file.
- `--tsconfig tsconfig.server.json`: Specifies the TypeScript configuration file for the server.

#### Start the Fastify Server

Open a new terminal and run the following command to start the development server:

```sh
npm run dev-node
```

The server will now run on port 3002. `tsx` will watch for any file changes, automatically restarting the Fastify server whenever updates are made.



# Server - Hono

# Hono

### Install Required Packages

To set up your Hono server with Remult, install the necessary packages:

```sh
npm install hono @hono/node-server remult
npm install --save-dev tsx
```

### Bootstrap Remult in the Backend

Remult is integrated into your backend using the `remultApi` adapter for Hono.

1. **Create the API File**

   Create a new `api.ts` file in the `src/server/` folder with the following code to set up the Remult middleware for Hono:

   ::: code-group

   ```ts [src/server/api.ts]
   import { remultApi } from 'remult/remult-hono'

   export const api = remultApi({})
   ```

   :::

2. **Register the Middleware**

   Update the `index.ts` file in your `src/server/` folder to include the Remult middleware. Add the following code:

::: code-group

```ts{3,8} [src/server/index.ts]
import { Hono } from 'hono'
import { serve } from '@hono/node-server'
import { api } from './api.js'

const app = new Hono()
app.get("/", (c) => c.text("Hono meets Remult!"));

app.route('', api)

serve(app, (info) => {
  console.log(`Listening on http://localhost:${info.port}`);
});
```

:::
::: warning ESM Configuration
When using ECMAScript modules (`esm`) in Hono, ensure you include the `.js` suffix when importing files, as shown in the `import { api } from './api.js'` statement.

Also, make sure that `"type": "module"` is set in your `package.json`.
:::

#### Create the Server's TypeScript Configuration

In the root folder, create a TypeScript configuration file named `tsconfig.server.json` for the Hono server:

::: code-group

```json [tsconfig.server.json]
{
  "compilerOptions": {
    "experimentalDecorators": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "outDir": "dist",
    "rootDir": "src",
    "module": "nodenext"
  },
  "include": ["src/server/**/*", "src/shared/**/*"]
}
```

:::

This configuration enables TypeScript decorators, ensures compatibility with ECMAScript modules, and specifies the file paths for the server and shared code.

#### Create an `npm` Script to Start the API Server

Add a new script in your `package.json` to start the Hono server in development mode:

::: code-group

```json [package.json]
"scripts": {
  "dev-node": "tsx watch --env-file=.env --tsconfig tsconfig.server.json src/server"
}
```

:::

- `tsx`: A TypeScript execution environment that watches for file changes and automatically restarts the server on each save.
- `--env-file=.env`: Ensures environment variables are loaded from the `.env` file.
- `--tsconfig tsconfig.server.json`: Specifies the TypeScript configuration file for the server.

#### Start the Hono Server

Open a new terminal and run the following command to start the development server:

```sh
npm run dev-node
```

`tsx` will watch for file changes, automatically restarting the Hono server whenever updates are made.



# Server - Elysia

# Elysia

### Install Required Packages

To set up your Elysia server with Remult, install the necessary packages:

```sh
npm install elysia @elysiajs/node remult
npm install --save-dev tsx
```

### Bootstrap Remult in the Backend

Remult is integrated into your backend using the `remultApi` adapter for Hono

:::info
Yes, the Elysia shares the same adapter as Hono!
:::

1. **Create the API File**

   Create a new `api.ts` file in the `src/server/` folder with the following code to set up the Remult middleware:

   ::: code-group

   ```ts [src/server/api.ts]
   import { remultApi } from 'remult/remult-hono'

   export const api = remultApi({})
   ```

   :::

2. **Register the Middleware**

   Update the `index.ts` file in your `src/server/` folder to include the Remult middleware. Add the following code:

::: code-group

```ts{3,7} [src/server/index.ts]
import { Elysia } from "elysia";
import { node } from "@elysiajs/node";
import { api } from "./api.js";

const elysiaApp = new Elysia({ adapter: node() })
  .get("/", () => "Elysia meets Remult!")
  .mount("", api.fetch);

elysiaApp.listen(3000, () =>
  console.log("Server running on http://localhost:3000")
);

```

:::
::: warning ESM Configuration
When using ECMAScript modules (`esm`) in Elysia, ensure you include the `.js` suffix when importing files, as shown in the `import { api } from './api.js'` statement.

Also, make sure that `"type": "module"` is set in your `package.json`.
:::

#### Create the Server's TypeScript Configuration

In the root folder, create a TypeScript configuration file named `tsconfig.server.json` for the Elysia server:

::: code-group

```json [tsconfig.server.json]
{
  "compilerOptions": {
    "experimentalDecorators": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "outDir": "dist",
    "rootDir": "src",
    "module": "nodenext"
  },
  "include": ["src/server/**/*", "src/shared/**/*"]
}
```

:::

This configuration enables TypeScript decorators, ensures compatibility with ECMAScript modules, and specifies the file paths for the server and shared code.

#### Create an `npm` Script to Start the API Server

Add a new script in your `package.json` to start the Elysia server in development mode:

::: code-group

```json [package.json]
"scripts": {
  "dev-node": "tsx watch --env-file=.env --tsconfig tsconfig.server.json src/server"
}
```

:::

- `tsx`: A TypeScript execution environment that watches for file changes and automatically restarts the server on each save.
- `--env-file=.env`: Ensures environment variables are loaded from the `.env` file.
- `--tsconfig tsconfig.server.json`: Specifies the TypeScript configuration file for the server.

#### Start the Elysia Server

Open a new terminal and run the following command to start the development server:

```sh
npm run dev-node
```

`tsx` will watch for file changes, automatically restarting the Elysia server whenever updates are made.



# Server - Hapi

# Hapi

### Install Required Packages

To set up your Hapi server with Remult, install the necessary packages:

```sh
npm install @hapi/hapi remult
npm install --save-dev tsx
```

### Bootstrap Remult in the Backend

Remult is integrated into your backend as a Hapi plugin.

1. **Create the API File**

   Create a new `api.ts` file in the `src/server/` folder with the following code to set up the Remult middleware for Hapi:

   ```ts
   // src/server/api.ts

   import { remultApi } from 'remult/remult-hapi'

   export const api = remultApi({})
   ```

2. **Register the Middleware**

   Update the `index.ts` file in your `src/server/` folder to include the Remult middleware. Add the following code:

   ```ts{5-7,10}
   // src/server/index.ts

   import { server } from '@hapi/hapi'
   import { api } from './api.js'

   const hapi = server({ port: 3002 })

   await hapi.register(api)

   hapi.start().then(() => console.log("Server started"))
   ```

   ::: warning ESM Configuration
   When using ECMAScript modules (`esm`) in Hapi, ensure you include the `.js` suffix when importing files, as shown in the `import { api } from './api.js'` statement.

   Also, make sure that `"type": "module"` is set in your `package.json`.
   :::

#### Create the Server's TypeScript Configuration

In the root folder, create a TypeScript configuration file named `tsconfig.server.json` for the Hapi server:

```json
{
  "compilerOptions": {
    "experimentalDecorators": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "outDir": "dist",
    "rootDir": "src",
    "module": "nodenext"
  },
  "include": ["src/server/**/*", "src/shared/**/*"]
}
```

This configuration enables TypeScript decorators, ensures compatibility with ECMAScript modules, and specifies the file paths for the server and shared code.

#### Create an `npm` Script to Start the API Server

Add a new script in your `package.json` to start the Hapi server in development mode:

```json
// package.json

"dev-node": "tsx watch --env-file=.env --tsconfig tsconfig.server.json src/server"
```

- `tsx`: A TypeScript execution environment that watches for file changes and automatically restarts the server on each save.
- `--env-file=.env`: Ensures environment variables are loaded from the `.env` file.
- `--tsconfig tsconfig.server.json`: Specifies the TypeScript configuration file for the server.

#### Start the Hapi Server

Open a new terminal and run the following command to start the development server:

```sh
npm run dev-node
```

The server will now run on port 3002. `tsx` will watch for file changes, automatically restarting the Hapi server whenever updates are made.



# Server - Koa

# Koa

### Install Required Packages

To set up your Koa server with Remult, run the following commands to install the necessary packages:

```sh
npm install koa koa-bodyparser remult
npm install --save-dev @types/koa @types/koa-bodyparser tsx
```

### Bootstrap Remult in the Backend

Remult is integrated into your backend as middleware for Koa.

1. **Create the API File**

   Create a new `api.ts` file in the `src/server/` folder with the following code to set up the Remult middleware:

   ```ts title="src/server/api.ts"
   // src/server/api.ts

   import { createRemultServer } from 'remult/server'

   export const api = createRemultServer()
   ```

2. **Register the Middleware**

   Update the `index.ts` file in your `src/server/` folder to include the Remult middleware. Add the following lines:

   ```ts title="src/server/index.ts" add={3,5,9}
   // src/server/index.ts

   import * as koa from 'koa'
   import * as bodyParser from 'koa-bodyparser'
   import { api } from './api.js'

   const app = new koa()

   app.use(bodyParser()) // Enables JSON body parsing for API requests

   app.use(async (ctx, next) => {
     const r = await api.handle(ctx.request) // Handle API requests with Remult
     if (r) {
       ctx.response.body = r.data
       ctx.response.status = r.statusCode
     } else {
       await next() // If not handled by Remult, pass on to the next middleware
     }
   })

   app.listen(3002, () => {
     console.log('Server started on port 3002')
   })
   ```

   ::: warning ESM Configuration
   In this tutorial, we are using ECMAScript modules (`esm`) for the Node.js server. When importing files, you must include the `.js` suffix (as shown in the `import { api } from "./api.js"` statement).

   Additionally, make sure to set `"type": "module"` in your `package.json` file.
   :::

#### Create the Server's TypeScript Configuration

In the root folder, create a TypeScript configuration file named `tsconfig.server.json` to manage the server's settings:

```json
{
  "compilerOptions": {
    "experimentalDecorators": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "outDir": "dist",
    "rootDir": "src",
    "module": "nodenext"
  },
  "include": ["src/server/**/*", "src/shared/**/*"]
}
```

This configuration enables TypeScript decorators, ensures compatibility with ECMAScript modules, and specifies the file paths for the server and shared code.

#### Create an `npm` Script to Start the API Server

To simplify the development process, add a new script in your `package.json` file to start the Koa server in development mode:

```json
// package.json

"dev-node": "tsx watch --env-file=.env --tsconfig tsconfig.server.json src/server"
```

- `tsx`: A TypeScript Node.js execution environment that watches for file changes and automatically restarts the server on each save.
- `--env-file=.env`: Ensures environment variables are loaded from the `.env` file.
- `--tsconfig tsconfig.server.json`: Specifies the TypeScript configuration file for the server.

#### Start the Koa Server

Finally, open a new terminal and run the following command to start the development server:

```sh
npm run dev-node
```

The server will now run on port 3002. `tsx` will watch for any file changes, automatically restarting the server whenever updates are made.



# Server - nest

# Nest.js

### Bootstrap Remult in the Nest.js back-end

1. Create a `main.ts` file in the `src/` folder with the following code:

```ts title="src/main.ts"
// src/main.ts

import { NestFactory } from '@nestjs/core'
import { AppModule } from './app.module'
import { remultApi } from 'remult/remult-express'

async function bootstrap() {
  const app = await NestFactory.create(AppModule)

  app.use(remultApi({})) // Integrate Remult as middleware

  await app.listen(3002) // Start server on port 3002
}
bootstrap()
```

2. Add a simple `AppModule` in `src/app.module.ts`:

```ts title="src/app.module.ts"
// src/app.module.ts

import { Module } from '@nestjs/common'

@Module({})
export class AppModule {}
```

### Run the Nest.js server

Run the server with:

```sh
npm run start
```

Your Nest.js app with Remult is now up and running on port `3002`.



# Stacks - Database

<script setup>
  import Icon from '../../../components/Icon.vue'
</script>

# Choose a Database

By default, if no database provider is specified, Remult will use a simple JSON file-based database. This will store your data in JSON files located in the `db` folder at the root of your project.

<div style="display: grid; grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); gap: 5rem; margin-top: 2rem">
	<Icon tech="postgres" sizeIco=100 link="/docs/installation/database/postgresql" />
	<Icon tech="mysql" sizeIco=100 link="/docs/installation/database/mysql" />
	<Icon tech="mongodb" sizeIco=100 link="/docs/installation/database/mongodb" />
	<Icon tech="sqlite" sizeIco=100 link="/docs/installation/database/better-sqlite3" />
	<Icon tech="sqljs" sizeIco=100 link="/docs/installation/database/sqljs" />
	<Icon tech="mssql" sizeIco=100 link="/docs/installation/database/mssql" />
	<Icon tech="bun-sqlite" sizeIco=100 link="/docs/installation/database/bun-sqlite" />
	<Icon tech="turso" sizeIco=100 link="/docs/installation/database/turso" />
	<Icon tech="duckdb" sizeIco=100 link="/docs/installation/database/duckdb" />
	<Icon tech="oracle" sizeIco=100 link="/docs/installation/database/oracle" />
	<Icon tech="d1" sizeIco=100 link="/docs/installation/database/d1" />
	<Icon tech="json files" sizeIco=100 link="/docs/installation/database/json" />
</div>



# Database - PostgreSQL

# PostgreSQL

To set up PostgreSQL as the database provider for your Remult application, you'll need to configure the `dataProvider` property in the `api.ts` file.

### Step 1: Install the `node-postgres` package

Run the following command to install the necessary PostgreSQL client for Node.js:

```sh
npm i pg
```

### Step 2: Set the `dataProvider` Property

In the `api.ts` file, configure the `dataProvider` property to connect to your PostgreSQL database:

```ts{3,7,11-15}
import express from "express"
import { remultApi } from "remult/remult-express"
import { createPostgresDataProvider } from "remult/postgres"

const app = express()

const connectionString = "postgres://user:password@host:5432/database"

app.use(
  remultApi({
    dataProvider: createPostgresDataProvider({
      connectionString, // default: process.env["DATABASE_URL"]
      // configuration: {} // optional: a `pg.PoolConfig` object or "heroku"
    })
  })
)
```

### Alternative: Use an Existing PostgreSQL Connection

If you already have a PostgreSQL connection set up, you can pass it directly to Remult:

```ts
import { Pool } from 'pg'
import { SqlDatabase } from 'remult'
import { PostgresDataProvider } from 'remult/postgres'
import { remultApi } from 'remult/remult-express'

const pg = new Pool({
  connectionString: 'your-connection-string-here',
})

const app = express()

app.use(
  remultApi({
    dataProvider: new SqlDatabase(new PostgresDataProvider(pg)),
  }),
)
```

In this example, the `pg.Pool` is used to create the PostgreSQL connection, and `SqlDatabase` is used to interface with the `PostgresDataProvider`.



# Database - MySQL

# MySQL

### Step 1: Install `knex` and `mysql2`

Run the following command to install the required packages:

```sh
npm i knex mysql2
```

### Step 2: Set the `dataProvider` Property

In your `api.ts` file, configure the `dataProvider` to connect to your MySQL database using `Knex`:

```ts{3,9-18}
import express from "express"
import { remultApi } from "remult/remult-express"
import { createKnexDataProvider } from "remult/remult-knex"

const app = express()

app.use(
  remultApi({
    dataProvider: createKnexDataProvider({
      client: "mysql2", // Specify the MySQL client
      connection: {
        user: "your_database_user",
        password: "your_database_password",
        host: "127.0.0.1",
        database: "test",
      },
    }),
  })
)
```

### Alternative: Use an Existing Knex Provider

If you're already using a `knex` instance in your project, you can pass it directly to Remult:

```ts
import express from 'express'
import { KnexDataProvider } from 'remult/remult-knex'
import { remultApi } from 'remult/remult-express'
import knex from 'knex'

const knexDb = knex({
  client: 'mysql2',
  connection: {
    user: 'your_database_user',
    password: 'your_database_password',
    host: '127.0.0.1',
    database: 'test',
  },
})

const app = express()

app.use(
  remultApi({
    dataProvider: new KnexDataProvider(knexDb), // Use the existing knex instance
  }),
)
```



# Database - MongoDB

## MongoDB

To use MongoDB as the database provider for your Remult application, follow the steps below.

### Step 1: Install MongoDB Driver

Run the following command to install the `mongodb` package:

```sh
npm i mongodb
```

### Step 2: Set the `dataProvider` Property

In your `api.ts` or server file, configure the `dataProvider` to connect to your MongoDB database:

```ts{3-4,10-14}
import express from "express"
import { remultApi } from "remult/remult-express"
import { MongoClient } from "mongodb"
import { MongoDataProvider } from "remult/remult-mongo"

const app = express()

app.use(
  remultApi({
    dataProvider: async () => {
      const client = new MongoClient("mongodb://localhost:27017/local")
      await client.connect()
      return new MongoDataProvider(client.db("test"), client)
    }
  })
)
```

This setup connects to a MongoDB instance running on `localhost` and uses the `test` database. The `MongoDataProvider` manages the connection, allowing Remult to interact with MongoDB seamlessly.



# Database - SQLite3

Here’s the polished version of the **sqlite3** setup:

### SQLite3 Setup

This version of **SQLite3** works well even on platforms like StackBlitz.

### Step 1: Install SQLite3

Run the following command to install the `sqlite3` package:

```sh
npm i sqlite3
```

### Step 2: Configure the `dataProvider`

In your `api.ts` or server file, configure the `dataProvider` to connect to the SQLite database using **sqlite3**:

```ts
import express from 'express'
import { remultApi } from 'remult/remult-express'
import { SqlDatabase } from 'remult'
import sqlite3 from 'sqlite3'
import { Sqlite3DataProvider } from 'remult/remult-sqlite3'

const app = express()

app.use(
  remultApi({
    dataProvider: new SqlDatabase(
      new Sqlite3DataProvider(new sqlite3.Database('./mydb.sqlite')),
    ),
  }),
)
```

This configuration connects to an SQLite database stored in the `mydb.sqlite` file. The `Sqlite3DataProvider` is wrapped inside the `SqlDatabase` class, enabling Remult to work with SQLite databases smoothly across different environments, including StackBlitz.



# Database - Better SQLite3

Here’s the polished version of the **Better-sqlite3** setup:

### Better-sqlite3

To use **Better-sqlite3** as the database provider for your Remult application, follow these steps:

### Step 1: Install Better-sqlite3

Run the following command to install the `better-sqlite3` package:

```sh
npm i better-sqlite3
```

### Step 2: Configure the `dataProvider`

In your `api.ts` or server file, configure the `dataProvider` to connect to the SQLite database using **Better-sqlite3**:

```ts
import express from 'express'
import { remultApi } from 'remult/remult-express'
import { SqlDatabase } from 'remult'
import Database from 'better-sqlite3'
import { BetterSqlite3DataProvider } from 'remult/remult-better-sqlite3'

const app = express()

app.use(
  remultApi({
    dataProvider: new SqlDatabase(
      new BetterSqlite3DataProvider(new Database('./mydb.sqlite')),
    ),
  }),
)
```

This setup connects to an SQLite database stored in the `mydb.sqlite` file. The `BetterSqlite3DataProvider` is wrapped inside the `SqlDatabase` class to allow Remult to interact with SQLite efficiently.



# Database - sqljs

### sql.js

### Step 1: Install sql.js

Run the following command to install the `sql.js` package:

```sh
npm i sql.js
```

### Step 2: Configure the `dataProvider`

In your `api.ts` or server file, configure the `dataProvider` to use `sql.js`:

```ts
import express from 'express'
import { remultApi } from 'remult/remult-express'
import { SqlDatabase } from 'remult'
import initSqlJs from 'sql.js'
import { SqlJsDataProvider } from 'remult/remult-sql-js'

const app = express()

app.use(
  remultApi({
    dataProvider: new SqlDatabase(
      new SqlJsDataProvider(initSqlJs().then((SQL) => new SQL.Database())),
    ),
  }),
)
```

### Explanation:

- **sql.js**: This setup initializes an in-memory SQLite database using `sql.js`, a library that runs SQLite in the browser or in Node.js.
- **SqlJsDataProvider**: The `SqlJsDataProvider` is used to integrate the `sql.js` database as a Remult data provider.
- **Async Initialization**: The `initSqlJs()` function initializes the SQL.js engine and sets up the database instance.

This configuration allows you to use an in-memory SQLite database in your Remult application, powered by `sql.js`.



# Database - MSSQL

# Microsoft SQL Server

### Step 1: Install Required Packages

Install `knex` and `tedious` to enable Microsoft SQL Server integration.

```sh
npm i knex tedious
```

### Step 2: Configure the `dataProvider`

In your `index.ts` (or server file), configure the `dataProvider` to use Microsoft SQL Server with the following `knex` client configuration:

```ts{5,11-25}
// index.ts

import express from "express"
import { remultApi } from "remult/remult-express"
import { createKnexDataProvider } from "remult/remult-knex"

const app = express()

app.use(
  remultApi({
    dataProvider: createKnexDataProvider({
      // Knex client configuration for MSSQL
      client: "mssql",
      connection: {
        server: "127.0.0.1", // SQL Server address
        database: "test", // Your database name
        user: "your_database_user", // SQL Server user
        password: "your_database_password", // Password for the SQL Server user
        options: {
          enableArithAbort: true, // Required option for newer versions of MSSQL
          encrypt: false, // Set to true if using Azure
          instanceName: "sqlexpress", // Optional: Define the SQL Server instance name
        },
      },
    }),
  })
)
```

### Step 3: Use an Existing `knex` Provider (Optional)

If you have an existing `knex` instance, you can easily integrate it with Remult like this:

```ts
import express from 'express'
import { KnexDataProvider } from 'remult/remult-knex'
import { remultApi } from 'remult/remult-express'
import knex from 'knex'

const knexDb = knex({
  client: 'mssql', // Specify MSSQL as the client
  connection: {
    // Add your MSSQL connection details here
    server: '127.0.0.1',
    user: 'your_database_user',
    password: 'your_database_password',
    database: 'test',
  },
})

const app = express()

app.use(
  remultApi({
    dataProvider: new KnexDataProvider(knexDb), // Use your existing knex instance
  }),
)
```

### Explanation:

- **`tedious`**: The underlying driver used by `knex` to connect to SQL Server.
- **`client: "mssql"`**: Specifies that we are using Microsoft SQL Server.
- **`createKnexDataProvider`**: Allows you to use `knex` to connect to SQL Server as the data provider for Remult.
- **`options`**: The additional configuration for SQL Server, including `enableArithAbort` and `encrypt`.

This setup lets you easily connect Remult to Microsoft SQL Server using `knex` for query building and `tedious` as the driver.



# Database - Bun SQLite

### Bun:SQLite

### Step 1: Configure the `dataProvider`

In your `api.ts` or server file, configure the `dataProvider` to use `bun:sqlite` as follows:

```ts
import express from 'express'
import { remultApi } from 'remult/remult-express'
import { SqlDatabase } from 'remult'
import { Database } from 'bun:sqlite'
import { BunSqliteDataProvider } from 'remult/remult-bun-sqlite'

const app = express()

app.use(
  remultApi({
    dataProvider: new SqlDatabase(
      new BunSqliteDataProvider(new Database('./mydb.sqlite')),
    ),
  }),
)
```

### Explanation:

- **bun:sqlite**: This uses Bun's native SQLite database, `bun:sqlite`, to manage SQLite databases efficiently in a Bun-based environment.
- **BunSqliteDataProvider**: The `BunSqliteDataProvider` integrates the Bun SQLite database as a data provider for Remult.
- **SqlDatabase**: Wraps the `BunSqliteDataProvider` to make it compatible with Remult's SQL-based data provider system.

This setup allows you to use Bun's SQLite implementation as the database provider for your Remult application, leveraging Bun’s performance benefits with SQLite.



# Database - Turso

Here’s the polished version of the **Turso** setup:

### Turso Setup

### Step 1: Install Turso Client

Run the following command to install the `@libsql/client` package:

```sh
npm install @libsql/client
```

### Step 2: Configure the `dataProvider`

In your `api.ts` or server file, configure the `dataProvider` to connect to Turso using the Turso client:

```ts
import express from 'express'
import { remultApi } from 'remult/remult-express'
import { SqlDatabase } from 'remult'
import { createClient } from '@libsql/client'
import { TursoDataProvider } from 'remult/remult-turso'

const app = express()

app.use(
  remultApi({
    dataProvider: new SqlDatabase(
      new TursoDataProvider(
        createClient({
          url: process.env.TURSO_DATABASE_URL,
          authToken: process.env.TURSO_AUTH_TOKEN,
        }),
      ),
    ),
  }),
)
```

### Explanation:

- **Turso Client**: This configuration uses the `@libsql/client` package to connect to the Turso database.
- **Environment Variables**: Ensure you have `TURSO_DATABASE_URL` and `TURSO_AUTH_TOKEN` defined in your environment to securely pass the database connection URL and authentication token.
- **SqlDatabase**: The `TursoDataProvider` is wrapped with the `SqlDatabase` class, allowing seamless integration of Turso as a Remult data provider.

This setup allows you to use Turso as the backend database for your application.



# Database - DuckDb

## DuckDB

To use DuckDB as the database provider in your Remult-based application, follow these steps:

### Step 1: Install DuckDB

Run the following command to install `@duckdb/node-api`:

```sh
npm i @duckdb/node-api
```

### Step 2: Configure the `dataProvider`

In your `index.ts` (or server file), configure the `dataProvider` to use DuckDB:

```ts
import express from 'express'
import { remultApi } from 'remult/remult-express'
import { SqlDatabase } from 'remult' // [!code highlight]
import { DuckDBInstance } from '@duckdb/node-api' // [!code highlight]
import { DuckDBDataProvider } from 'remult/remult-duckdb' // [!code highlight]

const app = express()

app.use(
  remultApi({
    dataProvider: new SqlDatabase( // [!code highlight]
      new DuckDBDataProvider(
        (await DuckDBInstance.create(':memory:')).connect(),
      ), // [!code highlight]
    ), // [!code highlight]
  }),
)

app.listen(3000, () => console.log('Server is running on port 3000'))
```

### Explanation:

- **DuckDB setup**: The database is initialized with `DuckDBInstance.create(':memory:')` to create an in-memory database. Replace `':memory:'` with a file path if you want to persist the database to disk.
- **SqlDatabase**: `SqlDatabase` is used to connect Remult with DuckDB through the `DuckDBDataProvider`.

This setup allows you to use DuckDB as your database provider in a Remult project.



# Database - Oracle

## Oracle Database

To use an Oracle database as the data provider for your Remult-based application, follow these steps:

### Step 1: Install Required Packages

Install `knex` and `oracledb`:

```sh
npm i knex oracledb
```

### Step 2: Configure the `dataProvider`

In your `index.ts` (or server file), configure the `dataProvider` to use Oracle through `knex`:

```ts{5,11-19}
// index.ts

import express from "express"
import { remultApi } from "remult/remult-express"
import { createKnexDataProvider } from "remult/remult-knex"

const app = express()

app.use(
  remultApi({
    dataProvider: createKnexDataProvider({
      // Knex client configuration for Oracle
      client: "oracledb",
      connection: {
        user: "your_database_user",
        password: "your_database_password",
        connectString: "SERVER" // Specify your Oracle server connection string
      }
    })
  })
)

app.listen(3000, () => console.log("Server is running on port 3000"))
```

### Step 3: Using an Existing `knex` Provider

If you're already using a `knex` instance, you can easily plug it into Remult:

```ts
import express from 'express'
import { KnexDataProvider } from 'remult/remult-knex'
import { remultApi } from 'remult/remult-express'
import knex from 'knex'

const knexDb = knex({
  client: 'oracledb',
  connection: {
    user: 'your_database_user',
    password: 'your_database_password',
    connectString: 'SERVER',
  },
})

const app = express()

app.use(
  remultApi({
    dataProvider: new KnexDataProvider(knexDb), // Reuse your existing knex provider
  }),
)

app.listen(3000, () => console.log('Server is running on port 3000'))
```

### Explanation:

- **Knex configuration**: `client: "oracledb"` indicates you're using Oracle, and `connection` contains the necessary credentials and connection string.
- **Existing knex provider**: If you already have a `knex` instance, it can be reused directly with Remult.

This setup integrates Oracle into your Remult-based application.



# Database - D1

## Cloudflare D1

To use D1 as the database provider in your Remult-based application meant for deployment on Cloudflare, you'll need
to setup the remult-d1 data provider.

### Step 1: Install the `cloudflare` package

Run the following command to install the necessary `cloudflare`

```sh
npm i cloudflare
```

### Step 2: Set the `dataProvider` Property

In your `index.ts` or whichever server file in your framework where you define the remult api, `dataProvider` can be configured by:

```ts
import { createD1DataProvider } from 'remult/remult-d1'

// Consult your specific framework and wrangler.jsonc
// for how to obtain D1_BINDING.
// Cloudflare typically provides it via server environment variables
const dataProvider = createD1DataProvider(D1_BINDING)

// If you're using d1-http instead,
// then create the database provider by providing the appropriate credentials
const dataProviderHttp = createD1HttpDataProvider(){
  accountId: "--cloudflare--account--id",
  apiToken: "--cloudflare--api--token",
  //get this from wrangler.jsonc or cloudflare dashboard
  databaseId: "--the--uuid--of--this--database"
}
```

### Example in the framework SolidStart

```ts
// api.ts
import { remultApi as solidStartRemultApi } from "remult/remult-solid-start"
import { createD1DataProvider } from "remult/remult-d1"

function getServerEnv() {
  "user server"

  const event = getRequestEvent()
	return event.nativeEvent.context.cloudflare?.env as Env
}

// assumption: you have MY_D1 defined for your cloudflare project in wrangler.jsonc
export const remultApi = solidStartRemultApi({
	entities: [...],
	controllers: [...],
	dataProvider: createD1DataProvider(getServerEnv.MY_D1),
})

```



# Database - Json files

## JSON Files

You can store data in JSON files using Remult. Here's how to configure your server:

### Step 1: Configure the `dataProvider`

In your `index.ts` (or server file), configure the `dataProvider` to use JSON files as the storage mechanism:

```ts{5-6,12-14}
// index.ts

import express from "express"
import { remultApi } from "remult/remult-express"
import { JsonDataProvider } from "remult"
import { JsonEntityFileStorage } from "remult/server"

const app = express()

app.use(
  remultApi({
    dataProvider: async () =>
      new JsonDataProvider(new JsonEntityFileStorage("./db")) // Data will be stored in the 'db' folder
  })
)
```

### Explanation:

- **`JsonDataProvider`**: This is the data provider that will store your data in JSON format.
- **`JsonEntityFileStorage`**: Specifies the directory where the JSON files will be stored (in this case, `./db`).
- **`"./db"`**: The path where JSON files for entities will be created. Ensure the folder exists or it will be created automatically.

This configuration allows you to store and manage your application data in JSON files, ideal for small projects or quick setups.



# Server-side Code - Backend Methods

# Backend Methods

Backend methods run on the backend and are used to improve performance, execute server-only code (e.g., sending emails), or perform operations not accessible through the API.

## Static Backend Methods

Static backend methods represent the most straightforward type, transmitting their parameters to the backend and delivering their outcome to the frontend.

1. **Define the Backend Method:**

```typescript
import { BackendMethod, repo } from 'remult'
import { Task } from './Task'

export class TasksController {
  /**
   * Sets the completion status of all tasks.
   * @param {boolean} completed - The completion status to set for all tasks.
   */
  @BackendMethod({ allowed: true })
  static async setAll(completed: boolean) {
    const taskRepo = repo(Task)

    for (const task of await taskRepo.find()) {
      await taskRepo.save({ ...task, completed })
    }
  }
}
```

Each controller can house one or more backend methods, each serving distinct purposes tailored to your application's needs. In the provided example, the `TasksController` class contains a single backend method named `setAll`, responsible for setting the completion status of all tasks.

The method name, such as `setAll`, serves as the URL for the corresponding REST endpoint on the backend server. It's worth noting that you can configure a prefix for these endpoints using the `apiPrefix` option, providing flexibility in structuring your backend API routes.

The allowed: true parameter signifies that the backend method can be invoked by anyone. Alternatively, you can customize the authorization settings for finer control over who can access the method.

For instance, setting allow: Allow.authenticated restricts access to authenticated users only, ensuring that only logged-in users can utilize the method.

Similarly, specifying allow: 'admin' limits access to users with administrative privileges, granting access exclusively to administrators.

These options offer granular control over authorization, allowing you to tailor access permissions based on your application's specific requirements and security considerations.

2. **Register the Controller:**

```typescript
// Register TasksController in the controllers array of the remultApi options
export const api = remultApi({
  entities: [Task],
  controllers: [TasksController],
})
```

3. **Call from the Frontend:**

```typescript
await TasksController.setAll(true)
```

This example demonstrates how to define and use a static backend method, `setAll`, within the `TasksController` class. When called from the frontend, this method sets the completion status of all tasks to the specified value (`true` in this case). The method leverages Remult's `BackendMethod` decorator to handle the communication between the frontend and backend seamlessly.



# Server-side Code - Server-only Dependencies

# Backend only code

One of the main advantages of remult is that you write code once, and it runs both on the server and in the browser.

However, if you are using a library that only works on the server, the fact that the same code is bundled to the frontend can cause problems. For example, when you build an Angular project, you'll get `Module not found` errors.

This article will walk through such a scenario and how it can be solved.

For this example, our customer would like us to document each call to the `updatePriceOnBackend` method in a log file.

Our first instinct would be to add in the `products.controller.ts` file an import to `fs` (Node JS file system component) and write the following code:

```ts{1,10}
import * as fs from 'fs';
.....
@BackendMethod({allowed:true})
static async updatePriceOnBackend(priceToUpdate:number,remult?:Remult){
  let products = await remult.repo(Products).find();
  for (const p of products) {
      p.price.value += priceToUpdate;
      await p.save();
  }
  fs.appendFileSync('./logs/log.txt', new Date() + " " + remult.user.name + " update price\n");
}
```

::: danger Error
As soon as we do that, we'll get the following errors on the `ng-serve` terminal

```sh
ERROR in ./src/app/products/products.controller.ts
Module not found: Error: Can't resolve 'fs' in 'C:\try\test19\my-project\src\app\products'
i ｢wdm｣: Failed to compile.
```

:::

We get this error because the `fs` module on which we rely here is only relevant in the remult of a `Node JS` server and not in the context of the browser.

There are two ways to handle this:

## Solution 1 - exclude from bundler

::: tabs

== vite

### Exclude in `vite.config`

Instruct vite to exclude the `server-only` packages from the bundle

<!-- prettier-ignore-start -->
```ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
  build: {    // [!code ++]
    rollupOptions: {      // [!code ++]
      external: ['fs', 'nodemailer', 'node-fetch'], // [!code ++]
    }, // [!code ++]
  }, // [!code ++]
  optimizeDeps: {    // [!code ++]
    exclude: ['fs', 'nodemailer', 'node-fetch'], // [!code ++]
  }, // [!code ++]
})
```
<!-- prettier-ignore-end -->

== Webpack and Angular version <=16
Instruct `webpack` not to include the `fs` package in the `frontend` bundle by adding the following JSON to the main section of the project's `package.json` file.
_package.json_

```json
"browser": {
   "jsonwebtoken": false
}
```

- note that you'll need to restart the react/angular dev server.

== Angular 17

1. You'll need to either remove `types` entry in the `tsconfig.app.json` or add the types you need to that types array.
2. In `angular.json` you'll need to add an entry called `externalDependencies` to the `architect/build/options` key for your project

   ```json{21-23}
   // angular.json

   {
     "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
     "version": 1,
     "newProjectRoot": "projects",
     "projects": {
       "remult-angular-todo": {
         "projectType": "application",
         "schematics": {},
         "root": "",
         "sourceRoot": "src",
         "prefix": "app",
         "architect": {
           "build": {
             "builder": "@angular-devkit/build-angular:application",
             "options": {
               "outputPath": "dist/remult-angular-todo",
               "index": "src/index.html",
               "browser": "src/main.ts",
               "externalDependencies": [
                 "fs"
               ],
               "polyfills": [
                 "zone.js"
               ],
               //...

   ```

   :::

## Solution 2 - abstract the call

Abstract the call and separate it to backend only files and `inject` it only when we are running on the server.

**Step 1**, abstract the call - We'll remove the import to `fs,` and instead of calling specific `fs` methods, we'll define and call a method `writeToLog` that describes what we are trying to do:

<!-- prettier-ignore-start -->
```ts
import * as fs from 'fs'; // [!code --]

// We'll define an abstract `writeTiLog` function and use it in our code
static writeToLog:(textToWrite:string)=>void; // [!code ++]
.....
@BackendMethod({allowed:true})
static async updatePriceOnBackend(priceToUpdate:number,remult?:Remult){
  let products = await remult.repo(Products).find();
  for (const p of products) {
      p.price.value += priceToUpdate;
      await p.save();
  }
  fs.appendFileSync('./logs/log.txt', new Date() + " " + remult.user.name + " update price\n");  // [!code --]
  ProductsController.writeToLog(new Date() + " " + remult.user.name + " update price\n"); // [!code ++]
}

```

<!-- prettier-ignore-end -->

The method `writeToLog` that we've defined serves as a place holder which we'll assign to in the remult of the server.
It receives one parameter of type `string` and returns `void`.

**Step 2**, implement the method:
In the `/src/app/server` folder, we'll add a file called `log-writer.ts` with the following code:

```ts{3}
import * as fs from 'fs';
import { ProductsController } from '../products/products.controller';
ProductsController.writeToLog = what => fs.appendFileSync('./logs/log.txt', what);
```

Here we set the implementation of the `writeToLog` method with the actual call to the `fs` module.
This file is intended to only run on the server, so it'll not present us with any problem.

**Step 3**, load the `log-writer.ts` file:
In the `/src/app/server/server-init.ts` file, load the `log-writer.ts` file using an `import` statement

```ts{2}
import '../app.module';
import './log-writer'; //load the log-writer.ts file

import { Pool } from 'pg';
import { config } from 'dotenv';
import { PostgresDataProvider, PostgresSchemaBuilder } from '@remult/server-postgres';
import * as passwordHash from 'password-hash';

```

That's it - it'll work now.
::: tip
If you're still getting an error - check that you have a `logs` folder on your project :)
:::

## Additional Resources

Check out this video where I implemented a similar solution when running into the same problem using `bcrypt`:

<iframe width="560" height="315" src="https://www.youtube.com/embed/9lWQwAUcKEM?start=1035" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>



# Guides - Access Control

# Access Control

::: tip **Interactive Learning Available! 🚀**

Looking to get hands-on with this topic? Try out our new [**interactive tutorial**](https://learn.remult.dev/in-depth/7-access-control/1-field-level-control) on Access Control, where you can explore and practice directly in the browser. This guided experience offers step-by-step lessons to help you master Access Control in Remult with practical examples and exercises.

[Click here to dive into the interactive tutorial on Access Control!](https://learn.remult.dev/in-depth/7-access-control/1-field-level-control)

:::

Access control is essential for ensuring that users can only access resources they are authorized to in web applications. This article explores the various layers of access control, focusing on a framework that provides a granular approach to securing your application.

## Entity-Level Authorization

Entity-level authorization governs CRUD (Create, Read, Update, Delete) operations at the entity level. Each entity can define permissions for these operations using the following options:

- `allowApiRead`: Controls read access.
- `allowApiInsert`: Controls insert access.
- `allowApiUpdate`: Controls update access.
- `allowApiDelete`: Controls delete access.

Each option can be set to a boolean, a string role, an array of string roles, or an arrow function:

```typescript
// Allows all CRUD operations
@Entity("tasks", { allowApiCrud: true })

// Only users with the 'admin' role can update
@Entity("tasks", { allowApiUpdate: 'admin' })

// Only users with 'admin' or 'manager' roles can delete
@Entity("tasks", { allowApiDelete: ['admin', 'manager'] })

// Only the user 'Jane' can read
@Entity("tasks", { allowApiRead: () => remult.user?.name == 'Jane' })

// Only authenticated users can perform CRUD operations
@Entity("tasks", { allowApiCrud: Allow.authenticated })
```

## Row-Level Authorization

Row-level authorization allows control over which rows a user can access or modify.

### Authorization on Specific Rows

The `allowApiUpdate`, `allowApiDelete`, and `allowApiInsert` options can also accept a function that receives the specific item as the first parameter, allowing row-level authorization:

```ts
// Users can only update tasks they own
@Entity<Task>("tasks", { allowApiUpdate: task => task.owner == remult.user?.id })
```

### Filtering Accessible Rows

To limit the rows a user has access to, use the `apiPrefilter` option:

```ts
@Entity<Task>("tasks", {
  apiPrefilter: () => {
    // Admins can access all rows
    if (remult.isAllowed("admin")) return {}
    // Non-admins can only access rows where they are the owner
    return { owner: remult.user!.id }
  }
})
```

The `apiPrefilter` adds a filter to all CRUD API requests, ensuring that only authorized data is accessible through the API.

### Preprocessing Filters for API Requests

For more complex scenarios, you can use `apiPreprocessFilter` to dynamically modify the filter based on the specific request and additional filter information:

```ts
@Entity<Task>("tasks", {
  apiPreprocessFilter: async (filter, {getPreciseValues}) => {
    // Ensure that users can only query tasks for specific customers
    const preciseValues = await getPreciseValues();
    if (!preciseValues.customerId) {
      throw new ForbiddenError("You must specify a valid customerId filter");
    }
    return filter;
  }
})
```

In this example, `apiPreprocessFilter` uses the `getPreciseValues` method to ensure that users must specify a valid `customerId` filter when querying tasks, allowing for more granular control over the data that is accessible through the API.

**Note:** The `preciseValues` object includes the actual values that are used in the filter. For example, in the code sample above, if the `customerId` filter specifies the values `'1'`, `'2'`, and `'3'`, then `preciseValues.customerId` will be an array containing these values. This allows you to check and enforce specific filter criteria in your preprocessing logic.

This added note explains the significance of the `preciseValues` property and how it includes the actual values used in the filter, providing an example for clarity.

### Warning: API Filters Do Not Affect Backend Queries

It's important to note that `apiPrefilter` and `apiPreprocessFilter` only apply to API requests. They do not affect backend queries, such as those executed through backend methods or non-Remult routes.

For instance, in a sign-in scenario, a backend method might need to check all user records to verify a user's existence without exposing all user data through the API. Once authenticated, the user should only have access to their own record for updates.

### Backend Filters for Consistent Access Control

To apply similar filtering logic to backend queries, you can use `backendPrefilter` and `backendPreprocessFilter`:

```ts
@Entity<Task>("tasks", {
  backendPrefilter: () => {
    // Admins can access all rows
    if (remult.isAllowed("admin")) return {}
    // Non-admins can only access rows where they are the owner
    return { owner: remult.user!.id }
  },
  backendPreprocessFilter: async (filter, {getPreciseValues}) => {
    // Apply additional filtering logic for backend queries
    const preciseValues = await getPreciseValues(filter);
    if (!preciseValues.owner) {
      throw new ForbiddenError("You must specify a valid owner filter");
    }
    return filter;
  }
})
```

In this example, `backendPrefilter` and `backendPreprocessFilter` ensure that non-admin users can only access their own tasks in backend queries, providing consistent access control across both API and backend operations.

## Field-Level Authorization

Field-level authorization allows control over individual fields within an entity:

_Field level authorization happens after entity level authorization AND if it's allowed._

- `includeInApi`: Determines if the field is included in the API response.
- `allowApiUpdate`: Controls if a field can be updated. If false, any change to the field is ignored.

Examples:

```ts
// This field will not be included in the API response
@Fields.string({ includeInApi: false })
password = ""

// Only users with the 'admin' role can update this field
@Fields.boolean({ allowApiUpdate: "admin" })
admin = false

// Titles can only be updated by the task owner
@Fields.string<Task>({ allowApiUpdate: task => task.owner === remult.user!.id })
title=''

// This field can only be updated when creating a new entity
@Fields.string<Category>({ allowApiUpdate: (c) => getEntityRef(c).isNew() })
Description = ""
```

### Field Masking

To mask a field, combine a non-API field with a `serverExpression` that returns the masked value:

```ts
// This field is not included in the API response
@Fields.string({ includeInApi: false })
password = ""

// The field value is masked in the API response
@Fields.string<User>({
  serverExpression: () => "***",
  // Update the real password field when the masked field is changed
  saving: async (user, fieldRef, e) => {
    if (fieldRef.valueChanged()) {
      user.password = await User.hash(user.updatePassword)
    }
  },
})
updatePassword = ""
```

## BackendMethod Authorization

Backend methods use the `allowed` option to determine authorization:

```ts
// Only authenticated users can execute this method
@BackendMethod({ allowed: Allow.authenticated })
static async doSomething() {
  // something
}
```

The `allowed` option can receive a boolean, a string role, an array of role strings, or a function.

## Reusing Access Control Definitions in the Frontend

Access control definitions set in entities can be reused as a single source of truth in the frontend. This allows for consistent and centralized management of access control logic across your application. For example, in a React component, you can conditionally render UI elements based on the access control rules defined in the entity:

::: code-group

```tsx [React]
function UserComponent({ user }: { user: User }) {
  //...
  return (
    <tr>
      <td>{user.name}</td>
      {/* Only show the admin field if the user is allowed to see it */}
      {userRepo.fields.admin.includeInApi(user) && <td>{user.admin}</td>}
      {/* Only show the delete button if the user is allowed to delete the admin */}
      {userRepo.metadata.apiDeleteAllowed(user) && (
        <td>
          <button onClick={deleteUser}>Delete</button>
        </td>
      )}
    </tr>
  )
}
```

```html [Angular]
<tr>
  <td>{{user.name}}</td>
  <!-- Only show the admin field if the user is allowed to see it -->
  <td *ngIf="userRepo.fields.admin.includeInApi(user)">{{user.admin}}</td>
  <!-- Only show the delete button if the user is allowed to delete the admin-->
  <td *ngIf="userRepo.metadata.apiDeleteAllowed(user)">
    <button (click)="deleteUser(user)">Delete</button>
  </td>
</tr>
```

```vue [Vue]
<tr>
  <td>{{user.name}}</td>
  <!-- Only show the admin field if the user is allowed to see it -->
  <td v-if="userRepo.fields.admin.includeInApi(user)">{{user.admin}}</td>
  <!-- Only show the delete button if the user is allowed to delete the admin-->
  <td v-if="userRepo.metadata.apiDeleteAllowed(user)">
    <button @click="deleteUser(user)">Delete</button>
  </td>
</tr>
```

```svelte [Svelte]
<tr>
  <td>{{user.name}}</td>
  <!-- Only show the admin field if the user is allowed to see it -->
  {#if userRepo.fields.admin.includeInApi(user)}
  <td>{{user.admin}}</td>
  {/if}
  <!-- Only show the delete button if the user is allowed to delete the admin-->
  {#if userRepo.metadata.apiDeleteAllowed(user)}
  <td>
    <button (click)="deleteUser(user)">Delete</button>
  </td>
  {/if}
</tr>
```

:::

## Additional Resources

Check out this informative [YouTube video](https://www.youtube.com/watch?v=9lWQwAUcKEM). It discusses the concepts covered in this article and provides practical examples to help you understand how to implement robust access control in your applications.

---

This article provides a comprehensive overview of the layers of access control in web applications, offering a granular approach to securing your application at the entity, row, field, and method levels.



# Guides - Admin UI

# Admin UI

Enjoy a fully featured Admin UI for your entities, you can do CRUD operations on your entities, view their relationships via the Diagram entry, and ensure secure management with the same validations and authorizations as your application.

## Enabling the Admin UI

Add the Admin UI to your application by setting the `admin` option to `true` in the remult configuration.

```ts
export const api = remultApi({
  entities: [],
  admin: true, // Enable the Admin UI
})
```

### Tunning the Admin UI

You can pass some options to admin as well:

- `allow`, using [allowed](https://remult.dev/docs/access-control). `true`, `"admin"`, ...
- `customHtmlHead`, to add custom html to the head of the admin page. It's a function that receives remult as an argument.
- `requireAuthToken`, this will open settings dialog to set the bearer token directly.
- `disableLiveQuery`, this will disable live query for the admin ui. (can be overridden in the admin ui settings)

Example:

```ts
export const api = remultApi({
  entities: [],
  admin: {
    allow: 'admin', // Only for user having the "admin" role
    customHtmlHead: (r) =>
      `<title>Nice Admin! (${r.user?.name ?? 'Anonymous'})</title>
       <link href="https://remult.dev/favicon.png" rel="icon" type="image/png">`,
  },
})
```

## Accessing and Using the Admin UI

Navigate to `/api/admin` to access the Admin UI. Here, you can perform CRUD operations on your entities, view their relationships via the Diagram entry, and ensure secure management with the same validations and authorizations as your application.

![Remult Admin](/remult-admin.png)

## Features

- **Entity List**: On the left side of the screen you have the entity list, you can use the search field to search for entities.

- **Entity Details**: Clicking on an entity in the menu will open the entity details screen (in the middle), here you can view filter & paginate your data _(top right)_. You can also see all relations of entity by clicking on the arrow on the left of each row. The last column is dedicated for actions where you can edit or delete an entity. On top left you can also add a new entity by clicking on the `+`.

- **Entity Diagram**: Clicking on the Diagram entry will open the entity diagram screen, here you can see the entity relationships.

![Remult Admin Diagram](/remult-admin-diagram.png)

- **Settings**: On top left, you have a menu _(remult logo)_ where you can find various settings for your admin ui.
  - You want to confirm a delete all the time?
  - You want to display Labels or Keys?
  - Multiple options for automatic diagram layout (you want also do your own layout)
  - You don't use cookies? No problem, you can set your bearer token (it will only be in session)

## Demo in video

Watch this quick demo to see the Remult Admin UI in action:

<iframe width="560" height="315" src="https://www.youtube.com/embed/u7KG_vklHyA" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

This video showcases the key features and functionality of the Remult Admin UI, giving you a practical overview of how it can streamline your entity management process.



# Guides - Modules

# Modules

The module system arrived in `remult@3.0.6`, the idea is to pack features in a single place.
Like this, it will be possible to share features between projects in a more convinient way.

Here is the [definition](/docs/ref_remultserveroptions#modules).
::: info
Come on Discord to share your ideas around modules!
:::

## Styles

### Local modules

Essentially, a local module is a way to organize your own code into a single place. You still have the full control of the code, and you can use the full power of `remult` in it.

You can also move this folder to a different project without many hassle!

### Library modules

Here, you use a module via a library, you install it and enjoy it. This library will probably allow you some configuration & you can tweak things.

When you have a great improvement idea, you should report it to the library author and follow the process.

### Cloned modules

It's a bit of a mix of the two previous styles. You clone a module from a repository and use it in your project, now you "own" it. Like this, you can tweak it to your needs.

## Some conventions

### Folder structure

In `src`, we like to have a `modules` folder. You will find all your local modules here.

In a module, the first level of folder is for the client, and we have a `server` folder for the server side code. Like this:

```ts
|- modules
	|- myModule
		|- index.ts                 // client side code (Role_MyModule, ...)
		|- myModuleEntities.ts      // entities
		|- myModuleController.ts    // controllers
		|- server
			|- index.ts             // server side code
   |- ...
|- ...
```

### Alias

With alias, you can access your modules in a more convinient way.

Depending on your framework, it can vary, but essentially, you will have a `tsconfig.json` file in your project that look like this:

```json
{
  "compilerOptions": {
    "paths": {
      "$modules": ["./src/modules"],
      "$modules/*": ["./src/modules/*"]
    }
  }
}
```

You will then be able to access your modules like this:

```ts
import { myModule } from '$module/myModule/server'
```

### Roles

To manage well [Access Control](/docs/access-control) of our app, we use a lot `remult.user.roles` that contains the list of roles of the user.

In the end, `roles` is just an array of strings, but as we want to have a better DX, we use a `Roles` object to manage them. Like this, no typo, no missing role, etc.

Based on that, it's recommended to have a `Roles.ts` having the list of all the roles of the app _(including all modules roles)_.

```ts
// Roles.ts
export const Roles = {
  // app roles
  Admin: 'admin',
  CanStrartProcess_007: 'canStrartProcess_007',

  // modules roles
  ...Roles_Auth,
  // ...
} as const
```

To be use like `Roles.Admin`, `Roles.CanStrartProcess_007`, `Roles.MyModule_Admin`, etc.

In a module, you will also have a file `Roles_MyModule.ts` _(client side)_ having the list of all the roles of the module.

```ts
export const Roles_MyModule = {
  MyModule_Admin: 'MyModule.Admin',
  // MyModule_Read_Stuff: "MyModule.Read_Stuff",
} as const
```

Like this, module users will be able to get all these roles in their Roles object.



# Modules - Community modules

# Community modules

This page showcases a list of recommended community made modules.
We encourage you to create any missing modules and maybe get added to the list!

| Name                                                     | Description                                                                                                                                                          |
| -------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Better-Auth                                              | Using [@nerdfolio/remult-better-auth](https://github.com/nerdfolio/remult-better-auth) adapter. The easiest way to get the module is to do `npm init remult@latest`. |
| [ChangeLog](https://firstly.fun/docs/modules/changelog/) | A `firstly` module to help keeping track of changes in your entities by who and when.                                                                                |
| [Cron](https://firstly.fun/docs/modules/cron/)           | A `firstly` module based on [cron](https://www.npmjs.com/package/cron). Loging status of each job into a cron entity.                                                |
| [Mail](https://firstly.fun/docs/modules/mail/)           | A `firstly` module based on [nodemailer](https://www.npmjs.com/package/nodemailer). Easy setup, default mail structure, loging mail status.                          |



# Escape Hatches - Custom/SQL Filters

# Leveraging Custom Filters for Enhanced Data Filtering

In modern web applications, efficiently filtering data is essential for providing a seamless user experience. Whether it's an e-commerce platform filtering products, a task management system sorting tasks, or any other application that requires data manipulation, the ability to apply complex filters is crucial. Custom filters offer a powerful solution, enabling developers to create reusable, declarative, and versatile filters that are executed on the backend and easily utilized from the frontend. This article delves into the concept of custom filters, illustrating their advantages and practical applications.

## The Advantages of Custom Filters

Custom filters provide several benefits that make them an attractive choice for handling data filtering in web applications:

1. **Declarative and Readable:** Custom filters allow you to express filtering logic in a clear, declarative manner. This improves code readability and maintainability, making it easier to understand and modify filtering criteria.

2. **Reusability:** By encapsulating filtering logic in custom filters, you can reuse the same filters across different parts of your application, reducing code duplication and ensuring consistency in filtering behavior.

3. **Backend Execution:** Custom filters are evaluated on the backend, leveraging the full capabilities of the underlying database or data provider. This enables more efficient data processing and allows you to perform complex operations that would be difficult or impossible to handle on the frontend.

4. **Composability:** Custom filters can be combined with other filters, both custom and standard, allowing you to build complex filtering logic in a modular and maintainable way.

5. **Flexibility with Data Providers:** Custom filters can be used with various data providers, including SQL databases, in-memory JSON arrays, and others. This flexibility allows you to apply custom filters in different contexts and with different data storage solutions.

6. **Enhanced Security:** When using custom filters with parameterized queries or data provider-specific filtering methods, you can mitigate the risk of injection attacks and ensure that user input is properly sanitized.

## Practical Example: Filtering Orders in an E-Commerce Application

Consider an e-commerce application where you need to filter orders based on their status and creation year. Without custom filters, the filtering logic might be repetitive and scattered throughout the codebase. By using custom filters, you can encapsulate this logic in a reusable component, simplifying the code and making it more maintainable.

In the following sections, we'll explore how to implement custom filters in this scenario, demonstrating their advantages and how they can be used to create more efficient and readable code.

## The Problem with Repetitive Filtering

Consider a scenario where you have an `Order` entity, and you frequently need to filter orders that are considered "active" based on their status and creation year. Without custom filters, your code might look something like this:

```ts
await repo(Order).find({
  where: {
    status: ['created', 'confirmed', 'pending', 'blocked', 'delayed'],
    createdAt: {
      $gte: new Date(year, 0, 1),
      $lt: new Date(year + 1, 0, 1),
    },
  },
})
```

This code is not only repetitive but also clutters your application, making it harder to maintain. Moreover, it generates lengthy REST API calls, such as:

```
/api/orders?status.in=%5B%22created%22%2C%22confirmed%22%2C%22pending%22%2C%22blocked%22%2C%22delayed%22%5D&createdAt.gte=2023-12-31T22%3A00%3A00.000Z&createdAt.lt=2024-12-31T22%3A00%3A00.000Z
```

## Introducing Custom Filters

Custom filters allow you to refactor your filtering logic into a reusable and declarative component. Here's how you can define a custom filter for active orders:

```ts
class Order {
  //...
  static activeOrdersFor = Filter.createCustom<Order, { year: number }>(
    async ({ year }) => {
      return {
        status: ['created', 'confirmed', 'pending', 'blocked', 'delayed'],
        createdAt: {
          $gte: new Date(year, 0, 1),
          $lt: new Date(year + 1, 0, 1),
        },
      }
    },
  )
}
```

- **First Generic Parameter (`Order`):** This parameter specifies the entity class that the filter is associated with. In this case, it's the `Order` class. This is important because it ensures that the filter criteria you define are compatible with the fields and types of the `Order` entity.

- **Second Generic Parameter (`{ year: number }`):** This parameter defines the type of the argument that the filter will receive when executed. In this example, the filter expects an object with a single property `year` of type `number`. This allows you to pass dynamic values to the filter when you use it in a query, making the filter more flexible and reusable.

- **Callback Function (`async ({ year }) => { ... }`):** This function is where you define the actual filtering criteria. It receives an argument matching the type specified in the second generic parameter. Inside the function, you return an object representing the filter conditions. In this case, the conditions are based on the `status` and `createdAt` fields of the `Order` entity.

Now, you can use this custom filter in your queries:

```ts
await repo(Order).find({
  where: Order.activeOrders({ year }),
})
```

This generates a much simpler REST API call:

```
/api/orders?%24custom%24activeOrders=%7B%22year%22%3A2024%7D
```

## Composability of Custom Filters

One of the key advantages of custom filters is their ability to be composed with other filters. This means you can combine custom filters with regular filters or even other custom filters to build complex filtering logic.

Let's take a closer look at the example you provided:

```ts
await repo(Order).find({
  where: {
    customerId: '123',
    $and: [Order.activeOrders({ year })],
  },
})
```

In this query, we're filtering orders based on two criteria:

1. The `customerId` should be "123".
2. The order should satisfy the conditions defined in the `activeOrders` custom filter for the specified year.

By using the `$and` operator, we're able to combine the custom filter with a regular filter. This demonstrates the composability of custom filters, allowing you to build more complex and nuanced filtering logic while maintaining readability and reusability.

### More on Composability

The power of composability doesn't stop there. You can also combine multiple custom filters to create even more specific filters. For example, suppose you have another custom filter called `highValueOrders` that filters orders based on their total value:

```ts
class Order {
  //...
  static highValueOrders = Filter.createCustom<Order>(() => {
    return {
      totalValue: { $gt: 1000 },
    }
  })
}
```

You can then combine this with the `activeOrders` filter to find high-value active orders for a specific year:

```ts
await repo(Order).find({
  where: {
    $and: [Order.activeOrders({ year }), Order.highValueOrders()],
  },
})
```

This ability to compose filters allows you to create modular and reusable filtering logic, which can significantly improve the maintainability and clarity of your code.

### Evaluating Custom Filters on the Backend

One of the significant advantages of custom filters is that they are evaluated on the backend. This allows you to perform complex data-related operations that would be inefficient or impossible to do solely on the frontend. For instance, you can leverage database queries or other server-side logic to build your filtering criteria.

Let's examine the example you provided:

```ts
static activeOrders = Filter.createCustom<
  Order,
  { year: number; customerCity: string }
>(async ({ year, customerCity }) => {
  const customers = await repo(Customer).find({
    where: { city: customerCity },
  })
  return {
    customerId: { $in: customers.map((c) => c.id) },
    status: ["created", "confirmed", "pending", "blocked", "delayed"],
    createdAt: {
      $gte: new Date(year, 0, 1),
      $lt: new Date(year + 1, 0, 1),
    },
  }
})
```

In this example, the custom filter `activeOrders` now takes an additional parameter `customerCity`. The filter performs a database query to fetch all customers from the specified city. It then uses the IDs of these customers to filter orders that belong to them. This is combined with the existing criteria of filtering orders based on their status and creation year.

::: tip Key Points

- **Backend Evaluation:** The filter is evaluated on the backend, where it has access to the database and can perform efficient queries. This offloads complex data processing from the frontend to the backend, where it can be handled more effectively.
- **Complex Filtering:** By leveraging backend capabilities, you can create filters that involve complex operations, such as fetching related data from other tables or entities (in this case, fetching customers based on their city).
- **Asynchronous Operations:** Notice the use of `async` in the filter definition. This allows you to perform asynchronous operations, such as database queries, within your custom filter.
  :::

## Leveraging Database Capabilities with Raw SQL in Custom Filters

Since custom filters are **evaluated on the backend**, you have the opportunity to harness the raw capabilities of the underlying database. This can be particularly useful when you need to perform complex operations that are more efficiently handled by the database itself. For instance, you can use raw SQL queries to improve the performance or functionality of your custom filters.

Let's modify the `activeOrders` custom filter to use a raw SQL query for filtering orders based on the customer's city:

```ts
static activeOrders = Filter.createCustom<
  Order,
  { year: number; customerCity: string }
>(async ({ year, customerCity }) => {
  return {
    status: ["created", "confirmed", "pending", "blocked", "delayed"],
    createdAt: {
      $gte: new Date(year, 0, 1),
      $lt: new Date(year + 1, 0, 1),
    },
    $and: [
      SqlDatabase.rawFilter(({param}) =>  // [!code highlight]
        `"customerId" in (select id from customers where city = ${param(customerCity)})` // [!code highlight]
      ), // [!code highlight]
    ],
  }
})
```

In this example, we've added a `$and` condition that uses `SqlDatabase.rawFilter` to include a raw SQL fragment in our filter. This SQL fragment selects the IDs of customers from the specified city and uses them to filter the orders.

This generates the following sql:

```sql
select "id", "status", "customerId", "createdAt"
from "orders"
where "status" in ($2, $3, $4, $5, $6)
and "createdAt" >= $7
and "createdAt" < $8
and ("customerId" in (select id from customers where city = $9))
Order By "id"
```

#### Important Notes

- **Parameterized Queries:** It's crucial to use parameterized queries (e.g., `builder.param(customerCity)`) when incorporating user-supplied values into your SQL queries. This helps prevent SQL injection attacks by ensuring that user input is properly escaped.
- **Performance Considerations:** Leveraging raw SQL can lead to significant performance improvements, especially for complex queries. However, it's important to ensure that your SQL queries are well-optimized to avoid potential performance issues.

#### Usage Example

Using the custom filter remains straightforward:

```ts
await repo(Order).find({
  where: Order.activeOrders({ year: 2024, customerCity: 'New York' }),
})
```

### Using `dbNamesOf` with Table Names and Aliases

The `dbNamesOf` utility function can be customized to include the table name in the SQL queries. This is particularly useful for ensuring consistency between your entity definitions and your raw SQL queries.

Here's an updated example of the `activeOrders` custom filter using `dbNamesOf` with table names and aliases:

```ts
static activeOrders = Filter.createCustom<
  Order,
  { year: number; customerCity: string }
>(async ({ year, customerCity }) => {
  const order = await dbNamesOf(Order, { // [!code highlight]
    tableName: true, // [!code highlight]
  })
  const customer = await dbNamesOf(Customer, { // [!code highlight]
    tableName: "c", // [!code highlight]
  }) // [!code highlight]

  return {
    status: ["created", "confirmed", "pending", "blocked", "delayed"],
    createdAt: {
      $gte: new Date(year, 0, 1),
      $lt: new Date(year + 1, 0, 1),
    },
    $and: [
      SqlDatabase.rawFilter(({param}) => // [!code highlight]
        `${order.customerId} in (select ${customer.id} from ${customer} as c // [!code highlight]
           where ${customer.city} = ${param(customerCity)})` // [!code highlight]
      ),
    ],
  }
})
```

In this example:

- The `Order` table is referenced with its full name.
- The `Customer` table is aliased as `"c"`, and this alias is used in the SQL query.

### Explanation of `tableName` and Aliases

- **`tableName: true`:** By setting `tableName: true`, you indicate that you want to include the table name when referring to fields, resulting in SQL expressions like `"customer"."id"`.
- **Aliases:** You can use aliases for table names, which is particularly useful in complex join scenarios. For example, setting `tableName: "c"` would use the alias `"c"` for the table name in the SQL query.

### Resulting SQL Query

Using the `activeOrders` custom filter with the enhancements mentioned above would generate the following SQL query:

```sql
select "id", "status", "customerId", "createdAt"
from "orders"
where "status" in ($2, $3, $4, $5, $6)
and "createdAt" >= $7
and "createdAt" < $8
and ("orders"."customerId" in (select "c"."id" from "customers" as c
           where c."city" = $9))
Order By "id"
```

In this SQL query, the `Customer` table is aliased as `"c"`, and this alias is used throughout the query to ensure consistency with the entity definitions and to handle complex join scenarios effectively.

### SQL-Based Custom Filters: Unleashing the Power of Composability

The greatest advantage of using SQL-based custom filters lies in their composability and the ability to handle complex situations. By breaking down filtering logic into smaller, atomic custom filters, developers can compose these filters to create more sophisticated and nuanced filtering criteria. This modular approach not only enhances the readability and maintainability of the code but also allows for greater flexibility in constructing complex queries.

For instance, consider a scenario where you need to filter orders based on multiple criteria, such as status, creation year, customer location, and order value. By creating separate custom filters for each of these criteria, you can easily combine them to form a comprehensive filtering solution. This composability ensures that your filtering logic can adapt to various requirements without becoming convoluted or difficult to manage.

Furthermore, the ability to handle complex situations is a significant advantage of SQL-based custom filters. By leveraging the raw power of SQL, you can perform advanced operations such as subqueries, joins, and aggregate functions directly within your filters. This opens up a wide range of possibilities for data analysis and manipulation, enabling you to tackle complex filtering scenarios with ease.

SQL is a language that is widely recognized and understood by AI technologies such as ChatGPT, Copilot and others. This makes it possible to generate highly optimized queries with ease. These AI technologies can assist in writing SQL queries, ensuring they are efficient and effective. This is particularly beneficial when dealing with complex data structures and large datasets, where writing optimal queries can be challenging. With the assistance of AI, developers can focus more on the logic of their applications, while the AI handles the intricacies of SQL query optimization.

In summary, the composability of SQL-based custom filters, coupled with their ability to handle complex situations, makes them an invaluable tool for developers seeking to create flexible, efficient, and powerful data filtering solutions in their web applications.

### Using Raw Filters with Different Data Providers

Custom filters with raw filters are not limited to SQL databases. You can also use raw filters with other data providers, such as Knex or an in-memory JSON data provider. This flexibility allows you to leverage the power of raw filters in various contexts, depending on your application's needs.

#### Knex Example

Knex is a popular SQL query builder for Node.js. You can use Knex with custom filters to define complex filtering logic directly using the Knex query builder syntax.

```typescript
static idBetween = Filter.createCustom<Task, {
  from: number,
  to: number
}>(
  ({ from, to }) => {
    return KnexDataProvider.rawFilter(({ knexQueryBuilder }) => {
      knexQueryBuilder.andWhereBetween('id', [from, to]);
    });
  }
);
```

In this example, the `idBetween` custom filter uses Knex to filter `Task` entities whose `id` falls between the specified `from` and `to` values.

#### JSON Example

For applications that use an in-memory JSON data provider, you can define custom filters that operate directly on the JSON data.

```typescript
static titleLengthFilter = Filter.createCustom<Task, { minLength: number }>(
  ({ minLength }) => {
    return ArrayEntityDataProvider.rawFilter((item) => {
      return item.title?.length > minLength;
    });
  }
);
```

In this example, the `titleLengthFilter` custom filter filters `Task` entities based on the length of their `title` property, ensuring that it exceeds the specified `minLength`.

## Conclusion

Custom filters represent a powerful tool in the arsenal of web developers, offering a flexible and efficient way to handle data filtering in web applications. By encapsulating filtering logic into reusable components, custom filters not only enhance code readability and maintainability but also enable the execution of complex filtering operations on the backend. This leads to improved performance and security, as well as the ability to compose intricate filtering criteria with ease.

The versatility of custom filters extends to their compatibility with various data providers, from SQL databases to in-memory JSON arrays, allowing developers to leverage the most suitable data handling mechanisms for their specific use cases. Moreover, the declarative nature of custom filters ensures that the filtering logic remains clear and concise, facilitating easier debugging and future modifications.

In conclusion, adopting custom filters in your web development projects can significantly streamline the process of data filtering, resulting in cleaner, more efficient, and more secure code. By embracing this approach, developers can focus on delivering a seamless user experience, confident in the knowledge that their data filtering logic is both robust and adaptable.



# Escape Hatches - Direct Database Access

# Accessing the Underlying Database in Remult

While Remult provides a powerful abstraction for working with databases, there might be scenarios where you need to access the underlying database directly. This could be for performing complex queries, optimizations, or other database-specific operations that are not covered by Remult's API.

:::warning
Directly executing custom SQL can be dangerous and prone to SQL injection attacks. Always use parameterized queries and the `param` method provided by Remult to safely include user input in your queries.
:::

## Accessing SQL Databases

For SQL-based databases, Remult provides the SqlDatabase class to interact directly with the database and allows you to run raw SQL queries directly. This is useful for executing complex queries that involve operations like GROUP BY, bulk updates, and other advanced SQL features.

### Basic SQL Query

```typescript
const sql = SqlDatabase.getDb()
const result = await sql.execute('SELECT COUNT(*) AS count FROM tasks')
console.log(result.rows[0].count)
```

This approach is straightforward but can lead to inconsistencies if the database schema changes.

#### the `dbNamesOf` function:

The `dbNamesOf` function dynamically retrieves the database table and column names based on your entity definitions, ensuring that your queries stay in sync with your data model. This enhances consistency, maintainability, and searchability in your code.

```typescript
const tasks = await dbNamesOf(Task)
const sql = SqlDatabase.getDb()
const result = await sql.execute(`SELECT COUNT(*) AS count FROM ${tasks}`)
console.log(result.rows[0].count)
```

##### Create index example

```typescript
const tasks = await dbNamesOf(Task)
const sql = SqlDatabase.getDb()
await sql.execute(`CREATE INDEX idx_task_title ON ${tasks}(${tasks.title});`)
```

### Using Bound Parameters

The `param` method safely incorporates user input into the query, reducing the risk of SQL injection by using parameterized queries.

```typescript
const priceToUpdate = 5
const products = await dbNamesOf(Product)
const sql = SqlDatabase.getDb()
let command = sql.createCommand()
await command.execute(
  `UPDATE ${products} SET ${products.price} = ${
    products.price
  } + ${command.param(priceToUpdate)}`,
)
```

When executed, this code will run the following SQL:

```sql
UPDATE products SET price = price + $1
Arguments: { '$1': 5 }
```

### Leveraging EntityFilter for SQL Databases

The `filterToRaw` function converts Remult's `EntityFilter` objects into SQL where clauses, enabling you to incorporate complex filtering logic defined in your models into custom SQL queries. This allows for reusability and integration with backend filters.

#### Benefits of filterToRaw

- **Reusability**: Allows you to reuse complex filters defined in your Remult models in custom SQL queries.
- **Integration**: Respects any **backendPrefilter** and **backendPreprocessFilter** applied to your entities, ensuring consistent access control and data manipulation rules.

```typescript
const order = await dbNamesOf(Order)
const sql = SqlDatabase.getDb()
const command = sql.createCommand()
const filterSql = await SqlDatabase.filterToRaw(
  Order,
  {
    status: ['created', 'confirmed', 'pending', 'blocked', 'delayed'],
    createdAt: {
      $gte: new Date(year, 0, 1),
      $lt: new Date(year + 1, 0, 1),
    },
  },
  command,
)
const result = await command.execute(
  `SELECT COUNT(*) FROM ${order} WHERE ${filterSql}`,
)
console.log(result.rows[0].count)
```

Resulting SQL:

```sql
SELECT COUNT(*) FROM "orders"
WHERE "status" IN ($1, $2, $3, $4, $5) AND "createdAt" >= $6 AND "createdAt" < $7
```

Using `customFilter`:

```typescript
const order = await dbNamesOf(Order)
const sql = SqlDatabase.getDb()
const command = sql.createCommand()
const filterSql = await SqlDatabase.filterToRaw(
  Order,
  Order.activeOrders({ year, customerCity: 'London' }),
  command,
)
const result = await command.execute(
  `SELECT COUNT(*) FROM ${order} WHERE ${filterSql}`,
)
console.log(result.rows[0].count)
```

Resulting SQL:

```sql
SELECT COUNT(*) FROM "orders"
WHERE "status" IN ($1, $2, $3, $4, $5) AND "createdAt" >= $6 AND "createdAt" < $7 AND ("orders"."customerId" IN (
      SELECT "customers"."id" FROM "customers"
             WHERE "customers"."city" = $8
        ))
```

## Accessing Other Databases

## Knex

```typescript
const tasks = await dbNamesOf(Task)
const knex = KnexDataProvider.getDb()
const result = await knex(tasks.$entityName).count()

console.log(result[0].count)
```

### Leveraging EntityFilter for Knex

```ts
const tasks = await dbNamesOf(Task)
const knex = KnexDataProvider.getDb()
const r = await knex(tasks.$entityName)
  .count()
  .where(await KnexDataProvider.filterToRaw(Task, { id: [1, 3] }))
console.log(r[0].count)
```

## MongoDB

```ts
const tasks = await dbNamesOf(Task)
const mongo = MongoDataProvider.getDb()
const r = await(await mongo.collection(tasks.$entityName)).countDocuments()
console.log(r)
```

### Leveraging EntityFilter for MongoDb

```ts
const tasks = await dbNamesOf(Task)
const mongo = MongoDataProvider.getDb()
const r = await(await mongo.collection(tasks.$entityName)).countDocuments(
  await MongoDataProvider.filterToRaw(Task, { id: [1, 2] }),
)
console.log(r)
```

## Native postgres

```ts
const tasks = await dbNamesOf(Task)
const sql = PostgresDataProvider.getDb()
const r = await sql.query(`select count(*) as c from ${tasks}`)
console.log(r.rows[0].c)
```

## Conclusion

Accessing the underlying database directly in Remult provides the flexibility to handle complex use cases that might not be covered by the ORM layer. However, it's important to use this capability judiciously and securely, especially when dealing with user input, to avoid potential security vulnerabilities like SQL injection. By leveraging utilities like `dbNamesOf` and `filterToRaw`.



# Escape Hatches - Using in Non-Remult Routes

# Using Remult in Non-Remult Routes

When using the CRUD api or [BackendMethods](./backendMethods.md), `remult` is automatically available. Still, there are many use cases where you may want to user remult in your own routes or other code without using `BackendMethods` but would still want to take advantage of `Remult` as an ORM and use it to check for user validity, etc...

If you tried to use the `remult` object, you may have got the error:

## Error: remult object was requested outside of a valid context, try running it within initApi or a remult request cycle <!-- I've placed this as header for search-->

Here's how you can use remult in this context, according to the server you're using:

::: tabs
== Express

### withRemult middleware

You can use remult as an express middleware for a specific route, using `api.withRemult`

```ts{1}
app.post('/api/customSetAll', api.withRemult, async (req, res) => {
  // ....
})
```

Or as an express middleware for multiple routes

```ts
app.use(api.withRemult) // [!code highlight]
app.post('/api/customSetAll', async (req, res) => {
  // ....
})
```

### withRemultAsync promise wrapper

Use the `api.withRemultAsync` method in promises

```ts
import express from 'express'
import { remultApi } from 'remult/remult-express'
import { remult, repo } from 'remult'

const app = express()
// ...
const api = remultApi({
  entities: [Task],
})
app.post('/api/customSetAll', async (req, res) => {
  // use remult in a specific piece of code // [!code highlight]
  await api.withRemultAsync(req, async () => {
    // [!code highlight]
    if (!remult.authenticated()) {
      res.sendStatus(403)
      return
    }
    if (!remult.isAllowed('admin')) {
      res.sendStatus(403)
      return
    }
    const taskRepo = repo(Task)
    for (const task of await taskRepo.find()) {
      task.completed = req.body.completed
      await taskRepo.save(task)
    }
    res.send()
  })
})
```

You can also use it without sending the request object, for non request related code

```ts{2}
setInterval(async () => {
  api.withRemultAsync(undefined, async () => {
    // ....
  })
}, 10000)
```

== Fastify

<!-- prettier-ignore-start -->
```ts 
import fastify from 'fastify'
import { remultApi } from 'remult/remult-fastify'

(async () => {
  const server = fastify()

  await server.register(remultApi({})) // [!code highlight]
  server.get('/api/test', async (req, res) => {
    return {
      result: await api.withRemult(req, () => remult.repo(Task).count()), // [!code highlight]
    }
  })


  server.listen({ port: 3000 })
})()
```

<!-- prettier-ignore-end -->

== Hono

<!-- prettier-ignore-start -->
```ts 
import { Hono } from 'hono'
import { remultApi } from 'remult/remult-hono'

const app = new Hono()

const api = remultApi({}) 
app.get('/test1', api.withRemult, async (c) => // [!code highlight]
  c.text('hello ' + (await repo(Task).count())),
)
app.route('', api)

export default app
```

== Next.js app router

```ts
// src/app/api/test/route.ts

import { NextResponse } from 'next/server'
import { repo } from 'remult'
import { Task } from '../../../shared/task'
import { api } from '../../../api'

export const dynamic = 'force-dynamic'

export async function GET(req: Request) {
  return api.withRemult(async () => {
    return NextResponse.json({
      result: repo(Task).count(),
      user: remult.user,
    })
  })
}
```

== Sveltekit

You can use the `withRemult` method in specific routes

```ts
// src/routes/api/test/+server.ts

import { json, type RequestHandler } from '@sveltejs/kit'
import { remult } from 'remult'
import { Task } from '../../../shared/Task'
import { api } from '../../../server/api'

export const GET: RequestHandler = async (event) => {
  return api.withRemult(event, async () =>
    json({ result: await remult.repo(Task).count() }),
  )
}
```

You can also define the withRemult as a hook, to make remult available throughout the application

```ts
// src/hooks.server.ts
import type { Handle } from '@sveltejs/kit'
import { sequence } from '@sveltejs/kit/hooks'
import { api as handleRemult } from './server/api'

export const handle = sequence(
  // Handle remult server side
  handleRemult,
)
```

<!-- prettier-ignore-start -->

== SolidStart

You can use the `withRemult` method in specific routes

```ts
// src/routes/api/test.ts

import { remult } from 'remult'
import { Task } from '../../../shared/Task'
import { api } from '../../../server/api'

export function GET() {
  return api.withRemult(event, async () =>
    ({ result: await remult.repo(Task).count() }),
  )
}
```

You can also use the same method for any "use server" function
```ts
export function getCount(){
  return api.withRemult(event, async () =>
   ({ result: await remult.repo(Task).count() }),
  )
}
```

You can also define the withRemult as a hook, to make remult available throughout the application

```ts
// src/hooks.server.ts
import type { Handle } from '@sveltejs/kit'
import { sequence } from '@sveltejs/kit/hooks'
import { api as handleRemult } from './server/api'

export const handle = sequence(
  // Handle remult server side
  handleRemult,
)
```

<!-- prettier-ignore-start -->

== Hapi
```ts 
import { type Plugin, server } from '@hapi/hapi'
import { remultApi } from 'remult/remult-hapi'

(async () => {
  const hapi = server({ port: 3000 })
  const api = remultApi({})
  await hapi.register(api) // [!code highlight]

  server.route({
    method: 'GET',
    path: '/api/test2',
    handler: async (request, h) => {
      return api.withRemult(request, async () => {
        return {
          result: await remult.repo(Task).count(),
        }
      })
    },
  })

  hapi.start()
})()
```
<!-- prettier-ignore-end -->

:::


# Escape Hatches - Avoiding Decorators

# Working without decorators

If you prefer to work without decorators, or use `remult` in a javascript project (without typescript) you can use the following:

## Entity

::: code-group

```ts [Typescript]
import { Entity, Fields, describeEntity } from 'remult'

export class Task {
  id!: string
  title = ''
  completed = false
}
describeEntity(
  Task,
  'tasks',
  {
    allowApiCrud: true,
  },
  {
    id: Fields.id(),
    title: Fields.string(),
    completed: Fields.boolean(),
  },
)
```

```js [Javascript]
import { Entity, Fields, describeEntity } from 'remult'

export class Task {
  id
  title = ''
  completed = false
}
describeEntity(
  Task,
  'tasks',
  {
    allowApiCrud: true,
  },
  {
    id: Fields.id(),
    title: Fields.string(),
    completed: Fields.boolean(),
  },
)
```

:::

This is the same entity that is detailed in the [Entities section of the tutorial](https://remult.dev/tutorials/react/entities.html)

## Static BackendMethod

```ts{12-14}
import { BackendMethod, describeBackendMethods, repo } from "remult";
import { Task } from "./Task";

export class TasksController {
  static async setAll(completed: boolean) {
    const taskRepo = repo(Task);
    for (const task of await taskRepo.find()) {
      await taskRepo.save({ ...task, completed });
    }
  }
}
describeBackendMethods(TasksController, {
  setAll: { allowed: "admin" }
})
```

This is the same backend method that is detailed in the [Backend methods of the tutorial](https://remult.dev/tutorials/react/backend-methods.html#refactor-from-front-end-to-back-end)



# Escape Hatches - Extensibility

# Extensibility

[Module Augmentation](https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation) in TypeScript allows you to extend existing types with custom properties or methods. This enhances the functionality of third-party libraries like `remult` without altering their source code, enabling seamless integration of custom features while maintaining type safety.

In Remult, you can use TypeScript's module augmentation to enhance your application with custom features. Here are some examples:

1. **Add more fields to the User object:** Extend the `UserInfo` interface to include additional fields like `email` and `phone`.
2. **Add custom options/metadata to fields and entities:** Extend the `FieldOptions` or `EntityOptions` interfaces to include custom properties such as `placeholderText` or `helpText`.
3. **Add fields/methods to the `remult.context` object:** Extend the `RemultContext` interface to include additional properties or methods that can be accessed throughout your code.

## Setting Up the types.d.ts File for Custom Type Extensions

To set up the `types.d.ts` file for custom type extensions in Remult:

1. **Create a TypeScript Declaration File:** Add a file named `types.d.ts` in the `src` folder of your project. This file will be used to declare custom type extensions, such as additional user info fields.

   ```ts
   // src/types.d.ts
   export {}

   declare module 'remult' {
     interface UserInfo {
       phone: string // [!code highlight]
       email: string // [!code highlight]
     }
   }
   ```

   The `export {}` is required to indicate that this file is a module, as per the [Vue.js documentation on augmenting global properties](https://vuejs.org/guide/typescript/options-api.html#augmenting-global-properties).

2. **Include the Declaration File in tsconfig:** Make sure that the `types.d.ts` file is included in the `include` section of your `tsconfig.json` file. If you have a separate `tsconfig` for the server, ensure that it's also added there.

   ```json
   // tsconfig.server.json
   {
     "compilerOptions": {
       //...
     },
     "include": ["src/server/**/*", "src/shared/**/*", "src/types.d.ts"] // [!code highlight]
   }
   ```

3. **Utilize the Custom Fields in Your Code:** Once you've defined custom fields in the `types.d.ts` file and ensured they're included in your `tsconfig.json`, you can start using them throughout your application. For instance, if you've added `phone` and `email` to the `UserInfo` interface, you can access these properties in your code as follows:

   ```ts
   // Accessing custom user info fields
   console.log(remult.user.phone)
   console.log(remult.user.email)
   ```

   This enables you to seamlessly integrate the new fields into your application's logic and user interface.

## Enhancing Field and Entity Definitions with Custom Options

One of the key motivations for adding custom options to `FieldOptions` or `EntityOptions` is to maintain consistency and centralize the definition of entities and fields in your application. By keeping these definitions close to the entity or field, you ensure a single source of truth for your application's data model. This approach enhances maintainability and readability, as all relevant information and metadata about an entity or field are located in one place. Additionally, it allows for easier integration with UI components, as custom options like `placeholderText` can be directly accessed and used in your frontend code.

For adding custom options to `FieldOptions` or `EntityOptions`, such as `placeholderText`:

1. **Extend FieldOptions:** In your `types.d.ts` file, extend the `FieldOptions` interface to include your custom options. For example:

   ```ts
   declare module 'remult' {
     interface FieldOptions<entityType, valueType> {
       placeholderText?: string // [!code highlight]
     }
   }

   export {}
   ```

2. **Set Custom Option:** Specify the `placeholderText` in your entity field options:

   ```ts
   import { Entity, Fields } from 'remult'

   @Entity('tasks', { allowApiCrud: true })
   export class Task {
     @Fields.id()
     id!: string

     @Fields.string({
       placeholderText: 'Please enter a task title', // [!code highlight]
     })
     title = ''

     @Fields.boolean()
     completed = false
   }
   ```

3. **Use in UI:** Access the custom option in your UI components:

   ```html{2}
   <input
     placeholder="{taskRepo.fields.title.options.placeholderText}"
   />
   ```

By following these steps, you can extend `FieldOptions` with custom options that can be utilized throughout your project.

### Extending Remult's `context` Property for Request-Specific Information

Augmenting Remult's `context` property is particularly useful because it allows you to store and access request-specific information throughout your code. This can be especially handy for including data from the request and utilizing it in entities or backend methods.

For example, you can add a custom property `origin` to the `RemultContext` interface:

```ts
declare module 'remult' {
  export interface RemultContext {
    origin?: string // [!code highlight]
  }
}
```

Then, set the `origin` property in the `initRequest` option in the `api.ts` file:

```ts
export const api = remultApi({
  initRequest: async (_, req) => {
    remult.context.origin = req.headers.origin // [!code highlight]
  },
  entities: [Task],
  //...
})
```

You can now use the `origin` property anywhere in your code, for example:

```ts
@BackendMethod({ allowed: Roles.admin })
static async doSomethingImportant() {
  console.log(remult.context.origin); // [!code highlight]
}
```

or in an entity's saving event:

```ts
@Entity<Task>("tasks", {
  saving: task => {
    task.lastUpdateDate = new Date();
    task.lastUpdateUser = remult.user?.name;
    task.lastUpdateOrigin = remult.context.origin; // [!code highlight]
  },
  //...
});
```

By leveraging module augmentation, you can tailor Remult to your specific needs, adding custom options and extending interfaces to suit your application's requirements.


# Integrations - Open API

# Adding Swagger and openApi

In short, swagger provides a quick UI that describes the api which is exposed by the application.

To add swagger to a `remult` application follow these steps:

1. Install the `swagger-ui-express` package:

   ```sh
   npm i swagger-ui-express
   npm i --save-dev @types/swagger-ui-express
   ```

2. In the `/src/server/index.ts` file add the following code:

   ```ts{2,6-9}
   import express from 'express';
   import swaggerUi from 'swagger-ui-express';
   import { remultApi } from 'remult/remult-express';

   const app = express();
   let api = remultApi({});

   app.use(api);
   const openApiDocument = api.openApiDoc({ title: "remult-react-todo" });
   app.get("/api/openApi.json", (req, res) => {res.json(openApiDocument)});
   app.use('/api/docs', swaggerUi.serve, swaggerUi.setup(openApiDocument));

   app.listen(3002, () => console.log("Server started"));
   ```

## Adding Swagger UI to a NextJs App

To add swagger UI to a `NextJs` application follow these steps:

1. Install the following packages:

   ```sh
   # With npm
   npm i swagger-ui-react
   npm i -D @types/swagger-ui-react

   # With yarn
   yarn add swagger-ui-react
   yarn add -D @types/swagger-ui-react
   ```

2. Get the openApi document from remultApiServer:

   ```ts
   // src/api.ts
   import { Task } from '@/shared/Task'
   import { TasksController } from '@/shared/TasksController'
   import { remultApi } from 'remult/remult-next'

   export const api = remultApi({
     admin: true,
     entities: [Task],
     controllers: [TasksController],
   })

   // Export this here 👇
   export const openApiDoc = api.openApiDoc({
     title: 'Todo App',
   })

   export const { POST, PUT, DELETE, GET } = api
   ```

3. Create a new page to render Swagger UI:

   ```tsx
   // src/app/api-doc/page.tsx
   import { openApiDoc } from '@/api' // 👈 Import the openApiDoc you exported earlier
   import ReactSwagger from './react-swagger'

   export default async function IndexPage() {
     return (
       <section className="container">
         <ReactSwagger spec={openApiDoc} />
       </section>
     )
   }
   ```

   ```tsx
   // src/app/api-doc/react-swagger.tsx
   'use client'

   import SwaggerUI from 'swagger-ui-react'
   import 'swagger-ui-react/swagger-ui.css'

   type Props = {
     spec: Record<string, any>
   }

   function ReactSwagger({ spec }: Props) {
     return <SwaggerUI spec={spec} />
   }

   export default ReactSwagger
   ```

4. Navigate to `http://localhost:3000/api-doc` to see the Swagger UI.

   ![Remult Admin](../public/example_remult-next-swagger-ui-page.png)

## Adding Scalar UI to SvelteKit

1. Install [Scalar](https://scalar.com) to get a modern OpenAPI UI with a built-in interactive playground:

   ```sh
   npm i @scalar/sveltekit
   ```

2. Export OpenAPI document schema from your Remult API in `src/server/api.ts` file:

   ```ts{8-11}
   import { Planet } from '$lib/entities';
   import { remultApi } from 'remult/remult-sveltekit';

   export const api = remultApi({
     entities: [Planet]
   });

   export const openApiDocument = api.openApiDoc({
    title: 'remult-planets',
    version: '1.0.0'
   });
   ```

3. Add a SvelteKit server route in `src/routes/api/[...remult]/openapi.json/+server.ts` to handle OpenAPI json file:

   ```ts
   import { json } from '@sveltejs/kit';
   import { openApiDocument } from '../../../../server/api';

   export const GET = () => {
    return json(openApiDocument);
   };
   ```

4. And finally create an endpoint for Scalar OpenAPI at `src/routes/api/[...remult]/docs/+server.ts`

   ```ts
   import { ScalarApiReference } from '@scalar/sveltekit'
   import type { RequestHandler } from './$types'
   

   const render = ScalarApiReference({
     url: '/api/openapi.json' // the above endpoint where the openapi spec is located
   });

   export const GET: RequestHandler = () => {
     return render();
   };

   ```

In this case the UI will be available at [http://localhost:5173/api/docs](http://localhost:5173/api/docs)

# Adding open api specific field options

Checkout the following example project that demos how to add `openApi` specific options to field options
[stackblitz](https://stackblitz.com/github/noam-honig/adding-open-api-options?file=server/build-open-api.ts,shared/task.ts)
[github](https://www.github.com/noam-honig/adding-open-api-options)



# Integrations - GraphQL

# Adding Graphql

To add graphql to a `remult` application follow these steps:

1. Install the `graphql-yoga` packages:
   ```sh
   npm i graphql-yoga
   ```

## Express:

In the `/src/server/index.ts` file add the following code:

```ts{3-4,12-22}
import express from 'express';
import { remultApi } from 'remult/remult-express';
import { createSchema, createYoga } from 'graphql-yoga'
import { remultGraphql } from 'remult/graphql';

const app = express()
const entities = [Task]
let api = remultApi({
   entities
});
app.use(api);
const { typeDefs, resolvers } = remultGraphql({
   entities
});
const yoga = createYoga({
   graphqlEndpoint: '/api/graphql',
   schema: (createSchema({
      typeDefs,
      resolvers
   }))
})
app.use(yoga.graphqlEndpoint, api.withRemult, yoga)
app.listen(3002, () => console.log("Server started"));
```

## Next App Router

```ts
// Next.js Custom Route Handler: https://nextjs.org/docs/app/building-your-application/routing/router-handlers
import { createYoga, createSchema } from 'graphql-yoga'
import { remultGraphql } from 'remult/graphql'
import { api } from '../../../api'
import { Task } from '../../../shared/task'

const { typeDefs, resolvers } = remultGraphql({
  entities: [Task],
})

const yoga = createYoga({
  // While using Next.js file convention for routing, we need to configure Yoga to use the correct endpoint
  graphqlEndpoint: '/api/graphql',
  schema: createSchema({
    typeDefs,
    resolvers,
  }),
  // Yoga needs to know how to create a valid Next response
  fetchAPI: { Response },
})

const handleRequest = (request: any, ctx: any) =>
  api.withRemult(() => yoga.handleRequest(request, ctx))

export { handleRequest as GET, handleRequest as POST }
```

## Svelte

`src/routes/api/graphql/+server.ts`

```ts
import type { RequestEvent } from '@sveltejs/kit'
import { createSchema, createYoga } from 'graphql-yoga'
import { remultGraphql } from 'remult/graphql'
import { Task } from '../../../shared/Task'

const { typeDefs, resolvers } = remultGraphql({
  entities: [Task],
})

const yogaApp = createYoga<RequestEvent>({
  schema: createSchema({
    typeDefs,
    resolvers,
  }),
  // While using Next.js file convention for routing, we need to configure Yoga to use the correct endpoint
  graphqlEndpoint: '/api/graphql',

  fetchAPI: { Response },
})

export { yogaApp as GET, yogaApp as OPTIONS, yogaApp as POST }
```



# Integrations - Standard Schema

# Standard Schema

Remult now supports the [Standard Schema](https://standardschema.dev/) specification, allowing you to use your Remult entities as type-safe validators that are compatible with any Standard Schema library.

## Overview

The Standard Schema specification provides a common interface for TypeScript validation libraries. By implementing this standard, Remult entities can be used as validators in any ecosystem that supports Standard Schema, making it easier to integrate with third-party tools and libraries.

Beside the `remult` ORM part, you don't need to add zod, valibot, ArkType, Effect,... to your project, you can use Remult entities as validators with any library that supports the Standard Schema specification.

## Basic Usage

Import the `std` function from Remult and use it to create a Standard Schema compatible validator from any entity:

```ts
import { standardSchema, Entity, Fields, repo } from 'remult'

@Entity('User')
class User {
  @Fields.id()
  id!: string

  @Fields.string({ required: true })
  name!: string

  @Fields.number()
  age?: number
}

// Create a Standard Schema validator for the entire entity
const userSchema = standardSchema(repo(User))

// Validate data with any Standard Schema library
const result = await validateWithAnyLibrary(userSchema, {
  name: 'John Doe',
  age: 30,
})

if (result.issues) {
  console.log('Validation errors:', result.issues)
} else {
  console.log('Valid data:', result.value)
}
```

## Field-Specific Validation

You can create validators that only check specific fields by passing field names as additional arguments:

```ts
// Validate only the age field
const ageSchema = standardSchema(repo(User), 'age')

const result = await validateWithAnyLibrary(ageSchema, { age: 30 })
// Returns: { value: { age: 30 } }

// Validate multiple specific fields
const nameAndAgeSchema = standardSchema(repo(User), 'name', 'age')

const result = await validateWithAnyLibrary(nameAndAgeSchema, {
  name: 'John Doe',
  age: 30,
  id: 'ignored', // This will be filtered out
})
// Returns: { value: { name: 'John Doe', age: 30 } }
```

## Validation with Custom Rules

The Standard Schema validator respects all your entity's validation rules, including custom validators and entity-level validation:

```ts
import { Validators } from 'remult'

@Entity('UserMail')
class UserMail {
  @Fields.string({ validate: [Validators.email] })
  email!: string

  @Fields.string()
  job = ''
}

// Email validation will be enforced
const emailSchema = standardSchema(repo(UserMail), 'email')

const result = await validateWithAnyLibrary(emailSchema, {
  email: 'invalid-email',
})
// Returns: { issues: [{ message: 'Invalid Email', path: ['email'] }] }

const validResult = await validateWithAnyLibrary(emailSchema, {
  email: 'user@example.com',
})
// Returns: { value: { email: 'user@example.com' } }
```

## Entity-Level Validation

Entity-level validation is also supported:

```ts
@Entity('Task', {
  validation(item) {
    if (item.userId && !item.userId.startsWith('user:')) {
      throw new Error(
        `Task ${item.title} must be assigned with someone starting with [user:]`,
      )
    }
  },
})
class Task {
  @Fields.string()
  title = ''

  @Fields.string({ required: true })
  userId = ''
}

const taskSchema = standardSchema(repo(Task))

const result = await validateWithAnyLibrary(taskSchema, {
  title: 'My Task',
  userId: '123', // Invalid format
})
// Returns: { issues: [{ message: 'Task My Task must be assigned with someone starting with [user:]', path: [] }] }
```

## Benefits

- **Interoperability**: Use Remult entities with any Standard Schema compatible library
- **Type Safety**: Full TypeScript support with inferred types
- **Consistency**: Same validation rules across your entire application
- **Flexibility**: Validate entire entities or specific fields
- **Standards Compliance**: Follows the official Standard Schema specification

The Standard Schema integration makes Remult entities more versatile and easier to integrate with the broader TypeScript ecosystem while maintaining all the benefits of Remult's validation system.



# API Reference - Entity

# Entity
Decorates classes that should be used as entities.
Receives a key and an array of EntityOptions.


#### example:
```ts
import  { Entity, Fields } from "remult";
@Entity("tasks", {
   allowApiCrud: true
})
export class Task {
   @Fields.id()
   id!: string;
   @Fields.string()
   title = '';
   @Fields.boolean()
   completed = false;
}
```
EntityOptions can be set in two ways:


#### example:
```ts
// as an object
@Entity("tasks",{ allowApiCrud:true })
```


#### example:
```ts
// as an arrow function that receives `remult` as a parameter
@Entity("tasks", (options,remult) => options.allowApiCrud = true)
```
## caption
A human readable name for the entity
## label
A human readable label for the entity. Can be used to achieve a consistent label for a field throughout the app


#### example:
```ts
<h1>Create a new item in {taskRepo.metadata.label}</h1>
```
## allowApiRead
Determines if this Entity is available for get requests using Rest Api


#### see:
 - [allowed](http://remult.dev/docs/allowed.html)
 - to restrict data based on a criteria, use [apiPrefilter](https://remult.dev/docs/ref_entity.html#apiprefilter)

## allowApiUpdate
Determines if this entity can be updated through the api.


#### see:
 - [allowed](http://remult.dev/docs/allowed.html)
 - [Access Control](https://remult.dev/docs/access-control)

## allowApiDelete
Determines if entries for this entity can be deleted through the api.


#### see:
 - [allowed](http://remult.dev/docs/allowed.html)
 - [Access Control](https://remult.dev/docs/access-control)

## allowApiInsert
Determines if new entries for this entity can be posted through the api.


#### see:
 - [allowed](http://remult.dev/docs/allowed.html)
 - [Access Control](https://remult.dev/docs/access-control)

## allowApiCrud
sets  the `allowApiUpdate`, `allowApiDelete` and `allowApiInsert` properties in a single set
## apiPrefilter
An optional filter that determines which rows can be queried using the API.
This filter is applied to all CRUD operations to ensure that only authorized data is accessible.

Use `apiPrefilter` to restrict data based on user profile or other conditions.


#### example:
```ts
// Only include non-archived items in API responses
apiPrefilter: { archive: false }
```


#### example:
```ts
// Allow admins to access all rows, but restrict non-admins to non-archived items
apiPrefilter: () => remult.isAllowed("admin") ? {} : { archive: false }
```


#### see:
[EntityFilter](https://remult.dev/docs/access-control.html#filtering-accessible-rows)
## apiPreprocessFilter
An optional function that allows for preprocessing or modifying the EntityFilter for a specific entity type
before it is used in API CRUD operations. This function can be used to enforce additional access control
rules or adjust the filter based on the current context or specific request.


#### example:
```typescript
@Entity<Task>("tasks", {
  apiPreprocessFilter: async (filter, { getPreciseValues }) => {
    // Ensure that users can only query tasks for specific customers
    const preciseValues = await getPreciseValues();
    if (!preciseValues.customerId) {
      throw new ForbiddenError("You must specify a valid customerId filter");
    }
    return filter;
  }
})
```
## backendPreprocessFilter
Similar to apiPreprocessFilter, but for backend operations.
## backendPrefilter
A filter that will be used for all queries from this entity both from the API and from within the backend.


#### example:
```ts
backendPrefilter: { archive:false }
```


#### see:
[EntityFilter](http://remult.dev/docs/entityFilter.html)
## defaultOrderBy
An order by to be used, in case no order by was specified


#### example:
```ts
defaultOrderBy: { name: "asc" }
```


#### example:
```ts
defaultOrderBy: { price: "desc", name: "asc" }
```
## saving
An event that will be fired before the Entity will be saved to the database.
If the `error` property of the entity's ref or any of its fields will be set, the save will be aborted and an exception will be thrown.
this is the place to run logic that we want to run in any case before an entity is saved.


#### example:
```ts
@Entity<Task>("tasks", {
  saving: async (task, e) => {
    if (e.isNew) {
      task.createdAt = new Date(); // Set the creation date for new tasks.
    }
    task.lastUpdated = new Date(); // Update the last updated date.
  },
})
```


#### see:
[Entity Lifecycle Hooks](http://remult.dev/docs/lifecycle-hooks)
## saved
A hook that runs after an entity has been successfully saved.


#### see:
[Entity Lifecycle Hooks](http://remult.dev/docs/lifecycle-hooks)
## deleting
A hook that runs before an entity is deleted.


#### see:
[Entity Lifecycle Hooks](http://remult.dev/docs/lifecycle-hooks)
## deleted
A hook that runs after an entity has been successfully deleted.


#### see:
[Entity Lifecycle Hooks](http://remult.dev/docs/lifecycle-hooks)
## validation
A hook that runs to perform validation checks on an entity before saving.
This hook is also executed on the frontend.


#### see:
[Entity Lifecycle Hooks](http://remult.dev/docs/lifecycle-hooks)
## dbName
The name of the table in the database that holds the data for this entity.
If no name is set, the `key` will be used instead.


#### example:
```ts
dbName:'myProducts'

You can also add your schema name to the table name
```


#### example:
```ts
dbName:'public."myProducts"'
```
## sqlExpression
For entities that are based on SQL expressions instead of a physical table or view


#### example:
```ts
@Entity('people', {
  sqlExpression:`select id,name from employees
                 union all select id,name from contractors`,
})
export class Person {
  @Fields.string()
  id=''
  @Fields.string()
  name=''
}
```
## id
An arrow function that identifies the `id` column to use for this entity


#### example:
```ts
//Single column id
@Entity<Products>("products", { id: 'productCode' })
```


#### example:
```ts
//Multiple columns id
@Entity<OrderDetails>("orderDetails", { id:['orderId:', 'productCode'] })
```
## entityRefInit

Arguments:
* **ref**
* **row**
## dataProvider
A function that allows customizing the data provider for the entity.


#### example:
```ts
dataProvider: (dp) => {
  if (!dp.isProxy) // usually indicates that we're on the backend
    return getASpacificDataProvider();
  return null
}
```
## apiRequireId
* **apiRequireId**



# API Reference - Field

# Field
Decorates fields that should be used as fields.
for more info see: [Field Types](https://remult.dev/docs/field-types.html)

FieldOptions can be set in two ways:


#### example:
```ts
// as an object
@Fields.string({ includeInApi:false })
title='';
```


#### example:
```ts
// as an arrow function that receives `remult` as a parameter
@Fields.string((options,remult) => options.includeInApi = true)
title='';
```
## valueType
The value type for this field
## caption
A human readable name for the field. Can be used to achieve a consistent caption for a field throughout the app


#### example:
```html
<input placeholder={taskRepo.metadata.fields.title.caption} />
```
## label
A human readable name for the field. Can be used to achieve a consistent label for a field throughout the app


#### example:
```html
<input placeholder={taskRepo.metadata.fields.title.label} />
```
## allowNull
If it can store `null` in the database.


#### default:
```ts
false
```
## required
If a value is required. Short-cut to say `validate: Validators.required`.


#### default:
```ts
false
```


#### see:
 - option [validate](https://remult.dev/docs/ref_field#validate)
 - validator [required](https://remult.dev/docs/ref_validators#required)

## includeInApi
Specifies whether this field should be included in the API. This can be configured
based on access control levels.


#### example:
```ts
// Do not include in the API
@Fields.string({ includeInApi: false })
password = '';
// Include in the API for 'admin' only
@Fields.number({ includeInApi: 'admin' })
salary = 0;
```


#### see:
 - [allowed](https://remult.dev/docs/allowed.html)
 - [Access Control](https://remult.dev/docs/access-control)

## allowApiUpdate
Determines whether this field can be updated via the API. This setting can also
be controlled based on user roles or other access control checks.

_It happens after entity level authorization AND if it's allowed._


#### example:
```ts
// Prevent API from updating this field
@Fields.string({ allowApiUpdate: false })
createdBy = remult.user?.id;
```


#### example:
```ts
// Allow API update only on new items
@Fields.string<Category>({ allowApiUpdate: (c) => getEntityRef(c).isNew() })
Description = ""
```


#### see:
 - [allowed](https://remult.dev/docs/allowed.html)
 - [Access Control](https://remult.dev/docs/access-control)

## validate
An arrow function that'll be used to perform validations on it


#### example:
```ts
@Fields.string({
  validate: Validators.required
})
*
```


#### example:
```ts
@Fields.string<Task>({
   validate: task=>task.title.length>3 ||  "Too Short"
})
```


#### example:
```ts
@Fields.string<Task>({
   validate: task=>{
     if (task.title.length<3)
         throw "Too Short";
  }
})
```


#### example:
```ts
@Fields.string({
   validate: (_, fieldValidationEvent)=>{
     if (fieldValidationEvent.value.length < 3)
         fieldValidationEvent.error = "Too Short";
  }
})
```
## saving
Will be fired before this field is saved to the server/database
## serverExpression
An expression that will determine this fields value on the backend and be provided to the front end
## dbName
The name of the column in the database that holds the data for this field. If no name is set, the key will be used instead.


#### example:
```ts
@Fields.string({ dbName: 'userName'})
userName=''
```
## sqlExpression
Used or fields that are based on an sql expressions, instead of a physical table column


#### example:
```ts
@Fields.integer({
  sqlExpression:e=> 'length(title)'
})
titleLength = 0;
@Fields.string()
title='';
```
## dbReadOnly
For fields that shouldn't be part of an update or insert statement
## valueConverter
The value converter to be used when loading and saving this field
## displayValue
an arrow function that translates the value to a display value
## defaultValue
an arrow function that determines the default value of the field, when the entity is created using the `repo.create` method
## inputType
The html input type for this field
## lazy
* **lazy**
## target
The entity type to which this field belongs
## key
The key to be used for this field



# API Reference - ValueConverter

# ValueConverter
Interface for converting values between different formats, such as in-memory objects, database storage,
JSON data transfer objects (DTOs), and HTML input elements.
## fromJson
Converts a value from a JSON DTO to the valueType. This method is typically used when receiving data
from a REST API call or deserializing a JSON payload.


#### returns:
The converted value.


#### example:
```ts
fromJson: val => new Date(val)
```

Arguments:
* **val** - The value to convert.
## toJson
Converts a value of valueType to a JSON DTO. This method is typically used when sending data
to a REST API or serializing an object to a JSON payload.


#### returns:
The converted value.


#### example:
```ts
toJson: val => val?.toISOString()
```

Arguments:
* **val** - The value to convert.
## fromDb
Converts a value from the database format to the valueType.


#### returns:
The converted value.


#### example:
```ts
fromDb: val => new Date(val)
```

Arguments:
* **val** - The value to convert.
## toDb
Converts a value of valueType to the database format.


#### returns:
The converted value.


#### example:
```ts
toDb: val => val?.toISOString()
```

Arguments:
* **val** - The value to convert.
## toDbSql
* **toDbSql**

Arguments:
* **val**
## toInput
Converts a value of valueType to a string suitable for an HTML input element.


#### returns:
The converted value as a string.


#### example:
```ts
toInput: (val, inputType) => val?.toISOString().substring(0, 10)
```

Arguments:
* **val** - The value to convert.
* **inputType** - The type of the input element (optional).
## fromInput
Converts a string from an HTML input element to the valueType.


#### returns:
The converted value.


#### example:
```ts
fromInput: (val, inputType) => new Date(val)
```

Arguments:
* **val** - The value to convert.
* **inputType** - The type of the input element (optional).
## displayValue
Returns a displayable string representation of a value of valueType.


#### returns:
The displayable string.


#### example:
```ts
displayValue: val => val?.toLocaleDateString()
```

Arguments:
* **val** - The value to convert.
## fieldTypeInDb
Specifies the storage type used in the database for this field. This can be used to explicitly define the data type and precision of the field in the database.


#### example:
```ts
// Define a field with a specific decimal precision in the database
@Fields.number({
  valueConverter: {
    fieldTypeInDb: 'decimal(18,8)'
  }
})
price=0;
```
## inputType
Specifies the type of HTML input element suitable for values of valueType.


#### example:
```ts
inputType = 'date';
```



# API Reference - Validation

# Validation

Validation is a key part of any application, and you will see that it's builtin Remult !

First of all, some props brings automatic validation, for example `required` and `minLength` for strings :

```ts
@Fields.string({ required: true, minLength: 5 })
title = ''
```

You can establish your own validation rules by using the `validate` prop and do any custom code you want :

```ts
@Fields.string({
   validate: (task)=> task.title.length > 5 || "too short"
})
title = ''
```

You want to focus only on the value?

```ts
@Fields.string({
   validate: valueValidator(value => value.length > 5)
})
title = ''
```

The `validate` prop can also use buildin validators like this :

```ts
import { Validators } from 'remult'

@Fields.string({
   validate: Validators.minLength(5)
})
title = ''
```

It supports array of validators as well :

```ts
import { Validators } from 'remult'

@Fields.string({
   validate: [
      Validators.minLength(5),
      Validators.maxLength(10),
      (task)=> task.title.startsWith('No') || "Need to start with No"
   ]
})
title = ''
```

Some validators like `unique` is running on the backend side, and nothing changes, you just have to use it :

```ts
import { Validators } from 'remult'

@Fields.string({
   validate: [
      Validators.minLength(5),
      Validators.unique()
   ]
})
title = ''
```

Also in custom validator you can check if you are in the backend or not :

```ts
import { Validators, isBackend } from 'remult'

@Fields.string({
   validate: [
      Validators.unique(),
      (task) => {
         if (isBackend()) {
            // check something else...
            // throw "a custom message"
         }
      }
   ]
})
title = ''
```

If you want to customize the error message, you can do it globally :

```ts
Validators.unique.defaultMessage = 'Existe déjà!'
```

::: tip
Remult entities can also be used as [Standard Schema](./standard-schema.md) compatible validators, making them interoperable with other validation libraries.
:::



# API Reference - Validators

# Validators
Class containing various field validators.
## constructor
* **Validators**
## defaultMessage
* **defaultMessage**
## email
Validator to check if a value is a valid email address.
## enum
Validator to check if a value exists in a given enum.
## in
Validator to check if a value is one of the specified values.
## max
Validator to check if a value is less than or equal to a maximum value.
## maxLength
Validator to check if a string's length is less than or equal to a maximum length.
## min
Validator to check if a value is greater than or equal to a minimum value.
## minLength
Validator to check if a string's length is greater than or equal to a minimum length.
## notNull
Validator to check if a value is not null.
## range
Validator to check if a value is within a specified range.
## regex
Validator to check if a value matches a given regular expression.
## relationExists
Validator to check if a related value exists in the database. By side-effect it loads relation data so it is directly available in [lifecycle hooks](https://remult.dev/docs/lifecycle-hooks)
## required
Validator to check if a value is required (not null or empty).
## unique
Validator to ensure a value is unique in the database.
## uniqueOnBackend
* **uniqueOnBackend**
## url
Validator to check if a value is a valid URL.



# API Reference - Relations

# Relations
* **Relations**
## constructor
* **Relations**
## toMany
Define a toMany relation between entities, indicating a one-to-many relationship.
This method allows you to establish a relationship where one entity can have multiple related entities.


#### returns:
A decorator function to apply the toMany relation to an entity field.

Example usage:
```ts
@Relations.toMany(() => Order)
orders?: Order[];

// or with a custom field name:
@Relations.toMany(() => Order, "customerId")
orders?: Order[];
```

Arguments:
* **toEntityType**
* **fieldInToEntity** - (Optional) The field in the target entity that represents the relation.
                      Use this if you want to specify a custom field name for the relation.
## toOne
Define a to-one relation between entities, indicating a one-to-one relationship.
If no field or fields are provided, it will automatically create a field in the database
to represent the relation.


#### returns:
A decorator function to apply the to-one relation to an entity field.

Example usage:
```ts
@Relations.toOne(() => Customer)
customer?: Customer;
```
```ts
Fields.string()
customerId?: string;

@Relations.toOne(() => Customer, "customerId")
customer?: Customer;
```
```ts
Fields.string()
customerId?: string;

@Relations.toOne(() => Customer, {
  field: "customerId",
  defaultIncluded: true
})
customer?: Customer;
```
```ts
Fields.string()
customerId?: string;

@Relations.toOne(() => Customer, {
  fields: {
    customerId: "id",
  },
})
customer?: Customer;
```

Arguments:
* **toEntityType**
* **options** - (Optional): An object containing options for configuring the to-one relation.
   * **caption** - A human readable name for the field. Can be used to achieve a consistent caption for a field throughout the app
   
   
   #### example:
   ```html
   <input placeholder={taskRepo.metadata.fields.title.caption} />
   ```
   * **label** - A human readable name for the field. Can be used to achieve a consistent label for a field throughout the app
   
   
   #### example:
   ```html
   <input placeholder={taskRepo.metadata.fields.title.label} />
   ```
   * **fields** - An object specifying custom field names for the relation.
   Each key represents a field in the related entity, and its value is the corresponding field in the source entity.
   For example, `{ customerId: 'id' }` maps the 'customerId' field in the related entity to the 'id' field in the source entity.
   This is useful when you want to define custom field mappings for the relation.
   * **field** - The name of the field for this relation.
   * **findOptions** - Find options to apply to the relation when fetching related entities.
   You can specify a predefined set of find options or provide a function that takes the source entity
   and returns find options dynamically.
   These options allow you to customize how related entities are retrieved.
   * **defaultIncluded** - Determines whether the relation should be included by default when querying the source entity.
   When set to true, related entities will be automatically included when querying the source entity.
   If false or not specified, related entities will need to be explicitly included using the `include` option.



# API Reference - RelationOptions

# RelationOptions
Options for configuring a relation between entities.
## caption
A human readable name for the field. Can be used to achieve a consistent caption for a field throughout the app


#### example:
```html
<input placeholder={taskRepo.metadata.fields.title.caption} />
```
## label
A human readable name for the field. Can be used to achieve a consistent label for a field throughout the app


#### example:
```html
<input placeholder={taskRepo.metadata.fields.title.label} />
```
## fields
An object specifying custom field names for the relation.
Each key represents a field in the related entity, and its value is the corresponding field in the source entity.
For example, `{ customerId: 'id' }` maps the 'customerId' field in the related entity to the 'id' field in the source entity.
This is useful when you want to define custom field mappings for the relation.
## field
The name of the field for this relation.
## findOptions
Find options to apply to the relation when fetching related entities.
You can specify a predefined set of find options or provide a function that takes the source entity
and returns find options dynamically.
These options allow you to customize how related entities are retrieved.
## defaultIncluded
Determines whether the relation should be included by default when querying the source entity.
When set to true, related entities will be automatically included when querying the source entity.
If false or not specified, related entities will need to be explicitly included using the `include` option.



# API Reference - Remult

# Remult
* **Remult**
## repo
Return's a `Repository` of the specific entity type


#### example:
```ts
const taskRepo = remult.repo(Task);
```


#### see:
[Repository](https://remult.dev/docs/ref_repository.html)

Arguments:
* **entity** - the entity to use
* **dataProvider** - an optional alternative data provider to use. Useful for writing to offline storage or an alternative data provider
## subscribeAuth
* **subscribeAuth**

Arguments:
* **listener**
## initUser
Fetches user information from the backend and updates the `remult.user` object.
Typically used during application initialization and user authentication.


#### returns:
A promise that resolves to the user's information or `undefined` if unavailable.
## authenticated
Checks if a user was authenticated
## isAllowed
checks if the user has any of the roles specified in the parameters


#### example:
```ts
remult.isAllowed("admin")
```


#### see:
[Allowed](https://remult.dev/docs/allowed.html)

Arguments:
* **roles**
## isAllowedForInstance
checks if the user matches the allowedForInstance callback


#### see:
[Allowed](https://remult.dev/docs/allowed.html)

Arguments:
* **instance**
* **allowed**
## useFetch
* **useFetch**

Arguments:
* **fetch**
## dataProvider
The current data provider
## constructor
Creates a new instance of the `remult` object.

Can receive either an HttpProvider or a DataProvider as a parameter - which will be used to fetch data from.

If no provider is specified, `fetch` will be used as an http provider

Arguments:
* **http**
## call
Used to call a `backendMethod` using a specific `remult` object


#### example:
```ts
await remult.call(TasksController.setAll, undefined, true);
```

Arguments:
* **backendMethod** - the backend method to call
* **classInstance** - the class instance of the backend method, for static backend methods use undefined
* **args** - the arguments to send to the backend method
## onFind
A helper callback that can be used to debug and trace all find operations. Useful in debugging scenarios

Arguments:
* **metadata**
* **options**
   * **limit** - Number of rows returned. _(Defaults to 100 in the browser)_
   
   
   #### example:
   ```ts
   await repo(Products).find({ limit: 10 })
   ```
   * **page** - Determines the page number to retrieve. Works in tandem with the `limit` option.
   
   
   #### example:
   ```ts
   await repo(Products).find({ page: 2 })
   ```
   * **load**
   * **include** - An option used to specify which related entities should be included when querying the source entity.
   It allows you to eagerly load related data to avoid N+1 query problems.
   
   
   #### param:
   An object specifying the related entities to include, their options, and filtering criteria.
   
   Example usage:
   ```ts
   const orders = await customerRepo.find({
     include: {
       // Include the 'tags' relation for each customer.
       tags: true,
     },
   });
   ```
   In this example, the `tags` relation for each customer will be loaded and included in the query result.
   
   
   #### see:
    - [Relations.toMany](/docs/ref_relations#tomany)
    - [Relations.toOne](/docs/ref_relations#toone)
    - [RelationOptions](/docs/ref_relations)
   
   * **select** - An option used to specify which fields should be included in the result.
   
   
   #### example:
   ```ts
   await repo(Task).find({ select: { id: true, title: true } })
   ```
   * **where** - filters the data
   
   
   #### example:
   ```ts
   await taskRepo.find({ where: { completed:false } })
   ```
   
   
   #### see:
   For more usage examples see [EntityFilter](https://remult.dev/docs/entityFilter.html)
   * **orderBy** - Determines the order of items returned .
   
   
   #### example:
   ```ts
   await repo(Products).find({ orderBy: { name: "asc" }})
   ```
   
   
   #### example:
   ```ts
   await repo(Products).find({ orderBy: { price: "desc", name: "asc" }})
   ```
   * **args**
## clearAllCache
* **clearAllCache**
## entityRefInit
A helper callback that is called whenever an entity is created.
## context
context that can be used to store custom information that will be disposed as part of the `remult` object.

`remult.context` is pre-filled in a framework-agnostic way with:
  - `headers.get(key: string)` _of request_
  - `headers.getAll()` _of request_

Check out the [extensibility section](/docs/custom-options#enhancing-field-and-entity-definitions-with-custom-options) for more custom options.
## apiClient
The api client that will be used by `remult` to perform calls to the `api`
## user
* **user**
## liveQueryStorage
* **liveQueryStorage**
## subscriptionServer
* **subscriptionServer**
## liveQueryPublisher
* **liveQueryPublisher**
## liveQuerySubscriber
* **liveQuerySubscriber**



# API Reference - ApiClient

# ApiClient
Interface for configuring the API client used by Remult to perform HTTP calls to the backend.
## httpClient
The HTTP client to use when making API calls. It can be set to a function with the `fetch` signature
or an object that has `post`, `put`, `delete`, and `get` methods. This can also be used to inject
logic before each HTTP call, such as adding authorization headers.


#### example:
```ts
// Using Axios
remult.apiClient.httpClient = axios;
```


#### example:
```ts
// Using Angular HttpClient
remult.apiClient.httpClient = httpClient;
```


#### see:
If you want to add headers using angular httpClient, see: https://medium.com/angular-shots/shot-3-how-to-add-http-headers-to-every-request-in-angular-fab3d10edc26


#### example:
```ts
// Using fetch (default)
remult.apiClient.httpClient = fetch;
```


#### example:
```ts
// Adding bearer token authorization
remult.apiClient.httpClient = (
  input: RequestInfo | URL,
  init?: RequestInit
) => {
  return fetch(input, {
    ...init,
    headers: authToken
      ? {
          ...init?.headers,
          authorization: 'Bearer ' + authToken,
        }
      : init?.headers,

    cache: 'no-store',
  })
}
```
## url
The base URL for making API calls. By default, it is set to '/api'. It can be modified to be relative
or to use a different domain for the server.


#### example:
```ts
// Relative URL
remult.apiClient.url = './api';
```


#### example:
```ts
// Different domain
remult.apiClient.url = 'https://example.com/api';
```
## subscriptionClient
The subscription client used for real-time data updates. By default, it is set to use Server-Sent Events (SSE).
It can be set to any subscription provider as illustrated in the Remult tutorial for deploying to a serverless environment.


#### see:
https://remult.dev/tutorials/react-next/deployment.html#deploying-to-a-serverless-environment
## wrapMessageHandling
A function that wraps message handling for subscriptions. This is useful for executing some code before
or after any message arrives from the subscription.
For example, in Angular, to refresh a specific part of the UI,
you can call the `NgZone` run method at this time.


#### example:
```ts
// Angular example
import { Component, NgZone } from '@angular/core';
import { remult } from "remult";

export class AppComponent {
  constructor(zone: NgZone) {
    remult.apiClient.wrapMessageHandling = handler => zone.run(() => handler());
  }
}
```



# API Reference - Repository

# Repository
used to perform CRUD operations on an `entityType`
## find
returns an array based on the provided options

Arguments:
* **options**
   * **limit** - Number of rows returned. _(Defaults to 100 in the browser)_
   
   
   #### example:
   ```ts
   await repo(Products).find({ limit: 10 })
   ```
   * **page** - Determines the page number to retrieve. Works in tandem with the `limit` option.
   
   
   #### example:
   ```ts
   await repo(Products).find({ page: 2 })
   ```
   * **load**
   * **include** - An option used to specify which related entities should be included when querying the source entity.
   It allows you to eagerly load related data to avoid N+1 query problems.
   
   
   #### param:
   An object specifying the related entities to include, their options, and filtering criteria.
   
   Example usage:
   ```ts
   const orders = await customerRepo.find({
     include: {
       // Include the 'tags' relation for each customer.
       tags: true,
     },
   });
   ```
   In this example, the `tags` relation for each customer will be loaded and included in the query result.
   
   
   #### see:
    - [Relations.toMany](/docs/ref_relations#tomany)
    - [Relations.toOne](/docs/ref_relations#toone)
    - [RelationOptions](/docs/ref_relations)
   
   * **select** - An option used to specify which fields should be included in the result.
   
   
   #### example:
   ```ts
   await repo(Task).find({ select: { id: true, title: true } })
   ```
   * **where** - filters the data
   
   
   #### example:
   ```ts
   await taskRepo.find({ where: { completed:false } })
   ```
   
   
   #### see:
   For more usage examples see [EntityFilter](https://remult.dev/docs/entityFilter.html)
   * **orderBy** - Determines the order of items returned .
   
   
   #### example:
   ```ts
   await repo(Products).find({ orderBy: { name: "asc" }})
   ```
   
   
   #### example:
   ```ts
   await repo(Products).find({ orderBy: { price: "desc", name: "asc" }})
   ```
   * **args**
## liveQuery
Using the same options as the find method, but subscribing to entity changes.

_Note that today it subscribes to entity changes, but not included entities [Feature Request](https://github.com/remult/remult/issues/712)!_


#### see:
[LiveQuery](/docs/ref_livequery)

Arguments:
* **options**
   * **limit** - Number of rows returned. _(Defaults to 100 in the browser)_
   
   
   #### example:
   ```ts
   await repo(Products).find({ limit: 10 })
   ```
   * **page** - Determines the page number to retrieve. Works in tandem with the `limit` option.
   
   
   #### example:
   ```ts
   await repo(Products).find({ page: 2 })
   ```
   * **load**
   * **include** - An option used to specify which related entities should be included when querying the source entity.
   It allows you to eagerly load related data to avoid N+1 query problems.
   
   
   #### param:
   An object specifying the related entities to include, their options, and filtering criteria.
   
   Example usage:
   ```ts
   const orders = await customerRepo.find({
     include: {
       // Include the 'tags' relation for each customer.
       tags: true,
     },
   });
   ```
   In this example, the `tags` relation for each customer will be loaded and included in the query result.
   
   
   #### see:
    - [Relations.toMany](/docs/ref_relations#tomany)
    - [Relations.toOne](/docs/ref_relations#toone)
    - [RelationOptions](/docs/ref_relations)
   
   * **select** - An option used to specify which fields should be included in the result.
   
   
   #### example:
   ```ts
   await repo(Task).find({ select: { id: true, title: true } })
   ```
   * **where** - filters the data
   
   
   #### example:
   ```ts
   await taskRepo.find({ where: { completed:false } })
   ```
   
   
   #### see:
   For more usage examples see [EntityFilter](https://remult.dev/docs/entityFilter.html)
   * **orderBy** - Determines the order of items returned .
   
   
   #### example:
   ```ts
   await repo(Products).find({ orderBy: { name: "asc" }})
   ```
   
   
   #### example:
   ```ts
   await repo(Products).find({ orderBy: { price: "desc", name: "asc" }})
   ```
   * **args**
## findFirst
returns the first item that matchers the `where` condition


#### example:
```ts
await taskRepo.findFirst({ completed:false })
```


#### example:
```ts
await taskRepo.findFirst({ completed:false },{ createIfNotFound: true })
```

Arguments:
* **where** - filters the data


#### see:
[EntityFilter](http://remult.dev/docs/entityFilter.html)
* **options**
   * **load**
   * **include** - An option used to specify which related entities should be included when querying the source entity.
   It allows you to eagerly load related data to avoid N+1 query problems.
   
   
   #### param:
   An object specifying the related entities to include, their options, and filtering criteria.
   
   Example usage:
   ```ts
   const orders = await customerRepo.find({
     include: {
       // Include the 'tags' relation for each customer.
       tags: true,
     },
   });
   ```
   In this example, the `tags` relation for each customer will be loaded and included in the query result.
   
   
   #### see:
    - [Relations.toMany](/docs/ref_relations#tomany)
    - [Relations.toOne](/docs/ref_relations#toone)
    - [RelationOptions](/docs/ref_relations)
   
   * **select** - An option used to specify which fields should be included in the result.
   
   
   #### example:
   ```ts
   await repo(Task).find({ select: { id: true, title: true } })
   ```
   * **where** - filters the data
   
   
   #### example:
   ```ts
   await taskRepo.find({ where: { completed:false } })
   ```
   
   
   #### see:
   For more usage examples see [EntityFilter](https://remult.dev/docs/entityFilter.html)
   * **orderBy** - Determines the order of items returned .
   
   
   #### example:
   ```ts
   await repo(Products).find({ orderBy: { name: "asc" }})
   ```
   
   
   #### example:
   ```ts
   await repo(Products).find({ orderBy: { price: "desc", name: "asc" }})
   ```
   * **useCache** - determines if to cache the result, and return the results from cache.
   * **createIfNotFound** - If set to true and an item is not found, it's created and returned
   * **args**
## findOne
returns the first item that matchers the `where` condition


#### example:
```ts
await taskRepo.findOne({ where:{ completed:false }})
```


#### example:
```ts
await taskRepo.findFirst({ where:{ completed:false }, createIfNotFound: true })
```

Arguments:
* **options**
   * **load**
   * **include** - An option used to specify which related entities should be included when querying the source entity.
   It allows you to eagerly load related data to avoid N+1 query problems.
   
   
   #### param:
   An object specifying the related entities to include, their options, and filtering criteria.
   
   Example usage:
   ```ts
   const orders = await customerRepo.find({
     include: {
       // Include the 'tags' relation for each customer.
       tags: true,
     },
   });
   ```
   In this example, the `tags` relation for each customer will be loaded and included in the query result.
   
   
   #### see:
    - [Relations.toMany](/docs/ref_relations#tomany)
    - [Relations.toOne](/docs/ref_relations#toone)
    - [RelationOptions](/docs/ref_relations)
   
   * **select** - An option used to specify which fields should be included in the result.
   
   
   #### example:
   ```ts
   await repo(Task).find({ select: { id: true, title: true } })
   ```
   * **where** - filters the data
   
   
   #### example:
   ```ts
   await taskRepo.find({ where: { completed:false } })
   ```
   
   
   #### see:
   For more usage examples see [EntityFilter](https://remult.dev/docs/entityFilter.html)
   * **orderBy** - Determines the order of items returned .
   
   
   #### example:
   ```ts
   await repo(Products).find({ orderBy: { name: "asc" }})
   ```
   
   
   #### example:
   ```ts
   await repo(Products).find({ orderBy: { price: "desc", name: "asc" }})
   ```
   * **useCache** - determines if to cache the result, and return the results from cache.
   * **createIfNotFound** - If set to true and an item is not found, it's created and returned
   * **args**
## findId
returns the items that matches the id. If id is undefined | null, returns null

Arguments:
* **id**
* **options**
   * **useCache** - determines if to cache the result, and return the results from cache.
   * **createIfNotFound** - If set to true and an item is not found, it's created and returned
## groupBy
Performs an aggregation on the repository's entity type based on the specified options.


#### returns:
The result of the aggregation.


#### example:
```ts
// Grouping by country and city, summing the salary field, and ordering by country and sum of salary:
const results = await repo.groupBy({
  group: ['country', 'city'],
  sum: ['salary'],
  where: {
    salary: { $ne: 1000 },
  },
  orderBy: {
    country: 'asc',
    salary: {
      sum: 'desc',
    },
  },
});

// Accessing the results:
console.log(results[0].country); // 'uk'
console.log(results[0].city); // 'London'
console.log(results[0].$count); // count for London, UK
console.log(results[0].salary.sum); // Sum of salaries for London, UK
```

Arguments:
* **options** - The options for the aggregation.
   * **group** - Fields to group by. The result will include one entry per unique combination of these fields.
   * **sum** - Fields to sum. The result will include the sum of these fields for each group.
   * **avg** - Fields to average. The result will include the average of these fields for each group.
   * **min** - Fields to find the minimum value. The result will include the minimum value of these fields for each group.
   * **max** - Fields to find the maximum value. The result will include the maximum value of these fields for each group.
   * **distinctCount** - Fields to count distinct values. The result will include the distinct count of these fields for each group.
   * **where** - Filters to apply to the query before aggregation.
   
   
   #### see:
   EntityFilter
   * **orderBy** - Fields and aggregates to order the results by.
   The result can be ordered by groupBy fields, sum fields, average fields, min fields, max fields, and distinctCount fields.
## aggregate
Performs an aggregation on the repository's entity type based on the specified options.


#### returns:
The result of the aggregation.


#### example:
```ts
// Aggregating  (summing the salary field across all items):
const totalSalary = await repo.aggregate({
  sum: ['salary'],
});
console.log(totalSalary.salary.sum); // Outputs the total sum of salaries
```

Arguments:
* **options** - The options for the aggregation.
## query
Fetches data from the repository in a way that is optimized for handling large sets of entity objects.

Unlike the `find` method, which returns an array, the `query` method returns an iterable `QueryResult` object.
This allows for more efficient data handling, particularly in scenarios that involve paging through large amounts of data.

The method supports pagination and aggregation in a single request. When aggregation options are provided,
the result will include both the items from the current page and the results of the requested aggregation.

The `query` method is designed for asynchronous iteration using the `for await` statement.


#### example:
```ts
// Basic usage with asynchronous iteration:
for await (const task of taskRepo.query()) {
  // Perform some operation on each task
}
```


#### example:
```ts
// Querying with pagination:
const query = taskRepo.query({
  where: { completed: false },
  pageSize: 100,
});

let paginator = await query.paginator();
console.log('Number of items on the current page:', paginator.items.length);
console.log('Total pages:', Math.ceil(paginator.aggregate.$count / 100));

if (paginator.hasNextPage) {
  paginator = await paginator.nextPage();
  console.log('Items on the next page:', paginator.items.length);
}
```


#### example:
```ts
// Querying with aggregation:
const query = await repo.query({
  where: { completed: false },
  pageSize: 50,
  aggregates: {
    sum: ['salary'],
    average: ['age'],
  }
});

let paginator = await query.paginator();
// Accessing paginated items
console.table(paginator.items);

// Accessing aggregation results
console.log('Total salary:', paginator.aggregates.salary.sum); // Sum of all salaries
console.log('Average age:', paginator.aggregates.age.average);  // Average age
```

Arguments:
* **options**
## count
Returns a count of the items matching the criteria.


#### see:
[EntityFilter](http://remult.dev/docs/entityFilter.html)


#### example:
```ts
await taskRepo.count({ completed:false })
```

Arguments:
* **where** - filters the data


#### see:
[EntityFilter](http://remult.dev/docs/entityFilter.html)
## validate
Validates an item


#### example:
```ts
const error = repo.validate(task);
if (error){
  alert(error.message);
  alert(error.modelState.title);//shows the specific error for the title field
}
// Can also be used to validate specific fields
const error = repo.validate(task,"title")
```

Arguments:
* **item**
* **fields**
## save
saves an item or item[] to the data source. It assumes that if an `id` value exists, it's an existing row - otherwise it's a new row


#### example:
```ts
await taskRepo.save({...task, completed:true })
```

Arguments:
* **item**
## insert
Insert an item or item[] to the data source


#### example:
```ts
await taskRepo.insert({title:"task a"})
```


#### example:
```ts
await taskRepo.insert([{title:"task a"}, {title:"task b", completed:true }])
```

Arguments:
* **item**
* **options**
   * **select**
## update
Updates an item, based on its `id`


#### example:
```ts
taskRepo.update(task.id,{...task,completed:true})
```

Arguments:
* **id**
* **item**
* **options**
   * **select**
## updateMany
Updates all items that match the `where` condition.

Arguments:
* **options**
   * **where** - filters the data
   
   
   #### see:
   [EntityFilter](http://remult.dev/docs/entityFilter.html)
   * **set**
## upsert
Inserts a new entity or updates an existing entity based on the specified criteria.
If an entity matching the `where` condition is found, it will be updated with the provided `set` values.
If no matching entity is found, a new entity will be created with the given data.

The `upsert` method ensures that a row exists based on the `where` condition: if no entity is found, a new one is created.
It can handle both single and multiple upserts.


#### returns:
A promise that resolves with the inserted or updated entity, or an array of entities if multiple options were provided.


#### example:
```ts
// Upserting a single entity: updates 'task a' if it exists, otherwise creates it.
taskRepo.upsert({ where: { title: 'task a' }, set: { completed: true } });
```


#### example:
```ts
// Upserting a single entity without additional `set` values: ensures that a row with the title 'task a' exists.
taskRepo.upsert({ where: { title: 'task a' } });
```


#### example:
```ts
// Upserting multiple entities: ensures both 'task a' and 'task b' exist, updating their `completed` status if found.
taskRepo.upsert([
  { where: { title: 'task a' }, set: { completed: true } },
  { where: { title: 'task b' }, set: { completed: true } }
]);
```

Arguments:
* **options** - The options that define the `where` condition and the `set` values. Can be a single object or an array of objects.
## delete
Deletes an Item

Arguments:
* **id**
## deleteMany
Deletes all items that match the `where` condition.

Arguments:
* **options**
   * **where** - filters the data
   
   
   #### see:
   [EntityFilter](http://remult.dev/docs/entityFilter.html)
## create
Creates an instance of an item. It'll not be saved to the data source unless `save` or `insert` will be called.

It's useful to start or reset a form taking your entity default values into account.

Arguments:
* **item**
## toJson
Translates an entity to a json object.
- Ready to be sent to the client _(Date & co are managed)_
- Strip out fields that are not allowed to be sent to the client! Check: [Field.includeInApi](http://remult.dev/docs/ref_field#includeinapi)


#### example:
```ts
const tasks = repo(Task).toJson(repo(Task).find())
```

Arguments:
* **item** - Can be an array or a single entity, awaitable or not
## fromJson
Translates a json object to an item instance.


#### example:
```ts
const data = // from the server
const tasks = repo(Task).fromJson(data)
```

Arguments:
* **data** - Can be an array or a single element
* **isNew** - To help the creation of the instance
## getEntityRef
returns an `entityRef` for an item returned by `create`, `find` etc...

Arguments:
* **item**
## fields
Provides information about the fields of the Repository's entity


#### example:
```ts
console.log(repo.fields.title.label) // displays the label of a specific field
console.log(repo.fields.title.options)// writes the options that were defined for this field
```
## metadata
The metadata for the `entity`


#### see:
[EntityMetadata](https://remult.dev/docs/ref_entitymetadata.html)
## addEventListener
* **addEventListener**

Arguments:
* **listener**
## relations
* **relations**

Arguments:
* **item**



# API Reference - RemultServerOptions

# RemultServerOptions
* **RemultServerOptions**
## entities
Entities to use for the api
## controllers
Controller to use for the api
## getUser
Will be called to get the current user based on the current request
## initRequest
Will be called for each request and can be used for configuration
## initApi
Will be called once the server is loaded and the data provider is ready
## dataProvider
Data Provider to use for the api.


#### see:
[Connecting to a Database](https://remult.dev/docs/databases.html).
## ensureSchema
Will create tables and columns in supporting databases.


#### default:
```ts
true

when set to true, it'll create entities that do not exist, and add columns that are missing.
```
## rootPath
The path to use for the api, if you want to use a different path adjust this field


#### default:
`/api`
## defaultGetLimit
The default limit to use for find requests that did not specify a limit
## logApiEndPoints
When set to true (default) it'll console log each api endpoint that is created
## subscriptionServer
A subscription server to use for live query and message channels
## liveQueryStorage
A storage to use to store live queries, relevant mostly for serverless scenarios or larger scales
## contextSerializer
Used to store the context relevant info for re running a live query
## admin
When set to true, will display an admin ui in the `/api/admin` url.
Can also be set to an arrow function for fine grained control


#### example:
```ts
admin: true
```


#### example:
```ts
admin: () => remult.isAllowed('admin')
```


#### see:
[allowed](http://remult.dev/docs/allowed.html)
## queueStorage
Storage to use for backend methods that use queue
## error
This method is called whenever there is an error in the API lifecycle.


#### example:
```ts
export const api = remultApi({
  error: async (e) => {
    if (e.httpStatusCode == 400) {
      e.sendError(500, { message: "An error occurred" })
    }
  }
})
```
## modules
Modules are here to group code by feature. [Module Guide](https://remult.dev/docs/modules)


#### example:
```ts
import { Module } from 'remult/server'

// create an analytics module
const analytics = () => new Module({
  key: 'analytics',
  priority: 11, // Default: 0, Prioritized by ascending order.
  entities: [AnalyticsEvent],
  controllers: [AnalyticsController],
  initApi: () => console.log('analytics module initialized'),
  initRequest: () => {},
  modules: [] // You can nest modules
})

// use the module in the remultApi
remultApi({
  modules: [
    analytics(),
  ]
})
```



# API Reference - EntityFilter

# EntityFilter

Used to filter the desired result set

### Basic example

```ts
where: {
  status: 1
}
```

( this will include only items where the status is equal to 1.

### In Statement

```ts
where:{ status:[1,3,5] }
//or
where:{ status:{ $in:[1,3,5]: } }
```

### Not Equal

```ts
where:{ status:{ "!=":1 }}
//or
where:{ status:{ $ne:1 }}
```

### Not in

```ts
where:{status:{ "!=":[1,2,3] }}
//or
where:{status:{ $ne:[1,2,3] }}
//or
where:{status:{ $nin:[1,2,3] }}
```

### Comparison operators

```ts
where:{ status:{ ">":1 }}
where:{ status:{ ">=":1 }}
where:{ status:{ "<":1 }}
where:{ status:{ "<=":1 }}
//or
where:{ status:{ $gt:1 }}
where:{ status:{ $gte:1 }}
where:{ status:{ $lt:1 }}
where:{ status:{ $lte:1 }}
```

### Contains

```ts
where: {
  name: {
    $contains: 'joe'
  }
}
```

### Not Contains

```ts
where: {
  name: {
    $notContains: 'joe'
  }
}
```

### Starts With

```ts
where: {
  name: {
    $startsWith: 'joe'
  }
}
```

### Ends With

```ts
where: {
  name: {
    $endsWith: 'joe'
  }
}
```

### Id Equal

```ts
where: {
  person: {
    $id: 123456
  }
}
```

### Multiple conditions has an `and` relationship

```ts
where: {
  status:1,
  archive:false
}
```

### $and

```ts
where: {
  $and: [{ status: 1 }, { archive: false }]
}
```

### $or

```ts
where: {
  $or: [{ status: 1 }, { archive: false }]
}
```

### $not

```ts
where: {
  $not: {
    status: 1
  }
}
```


# API Reference - EntityMetadata

# EntityMetadata
Metadata for an `Entity`, this metadata can be used in the user interface to provide a richer UI experience
## entityType
The class type of the entity
## key
The Entity's key also used as it's url
## fields
Metadata for the Entity's fields
## caption
A human readable caption for the entity. Can be used to achieve a consistent caption for a field throughout the app


#### example:
```ts
<h1>Create a new item in {taskRepo.metadata.caption}</h1>
```


#### see:
[EntityOptions.caption](/docs/ref_entity#caption)
## label
A human readable label for the entity. Can be used to achieve a consistent label for a field throughout the app


#### example:
```ts
<h1>Create a new item in {taskRepo.metadata.label}</h1>
```


#### see:
[EntityOptions.label](/docs/ref_entity#label)
## dbName
The name of the table in the database that holds the data for this entity.
If no name is set in the entity options, the `key` will be used instead.


#### see:
[EntityOptions.dbName](/docs/ref_entity#dbname)
## options
The options send to the `Entity`'s decorator


#### see:
[EntityOptions](/docs/ref_entity)
## apiUpdateAllowed
true if the current user is allowed to update an entity instance


#### see:
[EntityOptions.allowApiUpdate](/docs/ref_entity#allowapiupdate)


#### example:
```ts
if (repo(Task).metadata.apiUpdateAllowed(task)){
  // Allow user to edit the entity
}
```

Arguments:
* **item**
## apiReadAllowed
true if the current user is allowed to read from entity


#### see:
[EntityOptions.allowApiRead](/docs/ref_entity#allowapiread)


#### example:
```ts
if (repo(Task).metadata.apiReadAllowed){
  await taskRepo.find()
}
```
## apiDeleteAllowed
true if the current user is allowed to delete an entity instance


#### see:
[EntityOptions.allowApiDelete](/docs/ref_entity#allowapidelete)


#### example:
```ts
if (repo(Task).metadata.apiDeleteAllowed(task)){
  // display delete button
}
```

Arguments:
* **item**
## apiInsertAllowed
true if the current user is allowed to create an entity instance


#### see:
[EntityOptions.allowApiInsert](/docs/ref_entity#allowapiinsert)


#### example:
```ts
if (repo(Task).metadata.apiInsertAllowed(task)){
  // display insert button
}
```

Arguments:
* **item**
## getDbName
* **getDbName**
## idMetadata
Metadata for the Entity's id


#### see:
[EntityOptions.id](/docs/ref_entity#id) for configuration



# API Reference - FieldMetadata

# FieldMetadata
Metadata for a `Field`, this metadata can be used in the user interface to provide a richer UI experience
## valueType
The field's value type (number,string etc...)
## key
The field's member name in an object.


#### example:
```ts
console.log(repo(Task).metadata.fields.title.key);
// result: title
```
## caption
A human readable caption for the field. Can be used to achieve a consistent caption for a field throughout the app


#### example:
```ts
<input placeholder={taskRepo.metadata.fields.title.caption}/>
```


#### see:
[FieldOptions#caption](/docs/ref_field#caption) for configuration details
## label
A human readable label for the field. Can be used to achieve a consistent label for a field throughout the app


#### example:
```ts
<input placeholder={taskRepo.metadata.fields.title.label}/>
```


#### see:
[FieldOptions.label](/docs/ref_field#label) for configuration details
## dbName
The name of the column in the database that holds the data for this field. If no name is set, the key will be used instead.


#### example:
```ts
@Fields.string({ dbName: 'userName'})
userName=''
```


#### see:
[FieldOptions#dbName](/docs/ref_field#dbname) for configuration details
## options
The options sent to this field's decorator
## inputType
The `inputType` relevant for this field, determined by the options sent to it's decorator and the valueConverter in these options
## allowNull
if null is allowed for this field


#### see:
[FieldOptions#allowNull](/docs/ref_field#allownull) for configuration details
## target
The class that contains this field


#### example:
```ts
Task == repo(Task).metadata.fields.title.target //will return true
```
## getDbName
* **getDbName**
## isServerExpression
Indicates if this field is based on a server express
## dbReadOnly
indicates that this field should only be included in select statement, and excluded from update or insert. useful for db generated ids etc...


#### see:
[FieldOptions#dbReadOnly](/docs/ref_field#dbreadonly) for configuration details
## valueConverter
the Value converter for this field
## displayValue
Get the display value for a specific item


#### see:
[FieldOptions#displayValue](/docs/ref_field#displayvalue) for configuration details


#### example:
```ts
repo.fields.createDate.displayValue(task) //will display the date as defined in the `displayValue` option defined for it.
```

Arguments:
* **item**
## apiUpdateAllowed
Determines if the current user is allowed to update a specific entity instance.


#### example:
```ts
// Check if the current user is allowed to update a specific task
if (repo(Task).metadata.apiUpdateAllowed(task)){
  // Allow user to edit the entity
}
```


#### see:
[FieldOptions#allowApiUpdate](/docs/ref_field#allowapiupdate) for configuration details


#### returns:
True if the update is allowed.

Arguments:
* **item** - Partial entity instance to check permissions against.
## includedInApi
Determines if a specific entity field should be included in the API based on the current user's permissions.
This method checks visibility permissions for a field within a partial entity instance.


#### example:
```ts
const employeeRepo = remult.repo(Employee);
// Determine if the 'salary' field of an employee should be visible in the API for the current user
if (employeeRepo.fields.salary.includedInApi({ id: 123, name: 'John Doe' })) {
  // The salary field is included in the API
}
```


#### see:
[FieldOptions#includeInApi](/docs/ref_field#includeinapi) for configuration details


#### returns:
True if the field is included in the API.

Arguments:
* **item** - The partial entity instance used to evaluate field visibility.
## toInput
Adapts the value for usage with html input


#### example:
```ts
@Fields.dateOnly()
birthDate = new Date(1976,5,16)
//...
input.value = repo.fields.birthDate.toInput(person) // will return '1976-06-16'
```


#### see:
[ValueConverter#toInput](/docs/ref_valueconverter#toinput) for configuration details

Arguments:
* **value**
* **inputType**
## fromInput
Adapts the value for usage with html input


#### example:
```ts
@Fields.dateOnly()
birthDate = new Date(1976,5,16)
//...
person.birthDate = repo.fields.birthDate.fromInput(personFormState) // will return Date
```


#### see:
[ValueConverter#fromInput](/docs/ref_valueconverter#frominput) for configuration details

Arguments:
* **inputValue**
* **inputType**



# API Reference - Allowed

# Allowed

Throughout the api you'll see methods that use the `Allowed` data type, for example `allowApiRead` etc...

The `Allowed` data type can be set to one of the following value:

- true/false

```ts
{
  allowApiRead: true
}
```

- a Role - Checks if the current user has this role.

```ts
{
  allowApiRead: 'admin'
}
```

or with a constant

```ts
{
  allowApiRead: Roles.admin
}
```

- An Array of Roles - checks if the current user has at least one of the roles in the array

```ts
{
  allowApiRead: [Roles.admin, Roles.productManager]
}
```

- A function that get's a `remult` object as a parameter and returns true or false

```ts
{ allowApiRead: Allow.authenticated } }
```

or:

```ts
{ allowApiRead: () => remult.user.name === 'superman' } }
```

# AllowedForInstance

In some cases, the allowed can be evaluated with regards to a specific instance, for example `allowApiUpdate` can consider specific row values.
The Allowed for Instance method accepts two parameters:

1. The relevant `remult` object
2. The relevant entity instance

For Example:

```ts
@Entity<Task>("tasks", {
    allowApiUpdate: (task) => remult.isAllowed("admin") && !task!.completed
})
```



# API Reference - BackendMethod

# BackendMethod
Decorator indicating that the decorated method runs on the backend.
It allows the method to be invoked from the frontend while ensuring that the execution happens on the server side.
By default, the method runs within a database transaction, meaning it will either complete entirely or fail without making any partial changes.
This behavior can be controlled using the `transactional` option in the `BackendMethodOptions`.

For more details, see: [Backend Methods](https://remult.dev/docs/backendMethods.html).


#### example:
```typescript
@BackendMethod({ allowed: true })
async someBackendMethod() {
  // method logic here
}
```
## allowed
Determines when this `BackendMethod` can execute, see: [Allowed](https://remult.dev/docs/allowed.html)
## apiPrefix
Used to determine the route for the BackendMethod.


#### example:
```ts
{allowed:true, apiPrefix:'someFolder/'}
```
## transactional
Controls whether this `BackendMethod` runs within a database transaction. If set to `true`, the method will either complete entirely or fail without making any partial changes. If set to `false`, the method will not be transactional and may result in partial changes if it fails.


#### default:
```ts
true
```


#### example:
```ts
{allowed: true, transactional: false}
```
## queue
EXPERIMENTAL: Determines if this method should be queued for later execution
## blockUser
EXPERIMENTAL: Determines if the user should be blocked while this `BackendMethod` is running
## paramTypes
* **paramTypes**



# API Reference - QueryResult

# QueryResult
The result of a call to the `query` method in the `Repository` object.
## [asyncIterator]
returns an iterator that iterates the rows in the result using a paging mechanism


#### example:
```ts
for await (const task of taskRepo.query()) {
  await taskRepo.save({ ...task, completed });
}
```
## count
returns the number of rows that match the query criteria
## getPage
gets the items in a specific page

Arguments:
* **pageNumber**
## forEach
Performs an operation on all the items matching the query criteria

Arguments:
* **what**
## paginator
Returns a `Paginator` object that is used for efficient paging



# API Reference - Paginator

# Paginator
An interface used to paginating using the `query` method in the `Repository` object


#### example:
```ts

```


#### example:
```ts
const query = taskRepo.query({
  where: { completed: false },
  pageSize: 100,
})
const count = await query.count()
console.log('Paged: ' + count / 100)
let paginator = await query.paginator()
console.log(paginator.items.length)
if (paginator.hasNextPage) {
  paginator = await paginator.nextPage()
  console.log(paginator.items.length)
}
```
## items
the items in the current page
## hasNextPage
True if next page exists
## count
the count of the total items in the `query`'s result
## nextPage
Gets the next page in the `query`'s result set



# API Reference - LiveQuery

# LiveQuery
The `LiveQuery` interface represents a live query that allows subscribing to changes in the query results.
## subscribe
Subscribes to changes in the live query results.


#### returns:
A function that can be used to unsubscribe from the live query.


#### example:
```ts
// Subscribing to changes in a live query
const unsubscribe = repo(Task)
  .liveQuery({
    limit: 20,
    orderBy: { createdAt: 'asc' }
    //where: { completed: true },
  })
  .subscribe(info => setTasks(info.applyChanges));

// Later, to unsubscribe
unsubscribe();
```

Arguments:
* **next** - A function that will be called with information about changes in the query results.



# API Reference - LiveQueryChangeInfo

# LiveQueryChangeInfo
The `LiveQueryChangeInfo` interface represents information about changes in the results of a live query.
## items
The updated array of result items.
## changes
The changes received in the specific message. The change types can be "all" (replace all), "add", "replace", or "remove".
## applyChanges
Applies the changes received in the message to an existing array. This method is particularly useful with React
to update the component's state based on the live query changes.


#### returns:
The updated array of result items after applying the changes.


#### example:
```ts
// Using applyChanges in a React component with useEffect hook
useEffect(() => {
  return taskRepo
    .liveQuery({
      limit: 20,
      orderBy: { createdAt: 'asc' }
      //where: { completed: true },
    })
    .subscribe(info => setTasks(info.applyChanges));
}, []);
```

Arguments:
* **prevState** - The previous state of the array of result items.



# API Reference - Filter

# Filter
The `Filter` class is a helper class that focuses on filter-related concerns. It provides methods
for creating and applying filters in queries.
## getPreciseValues
Retrieves precise values for each property in a filter for an entity.


#### returns:
A promise that resolves to a FilterPreciseValues object containing the precise values for each property.


#### example:
```ts
const preciseValues = await Filter.getPreciseValues(meta, {
  status: { $ne: 'active' },
  $or: [
    { customerId: ["1", "2"] },
    { customerId: "3" }
  ]
});
console.log(preciseValues);
// Output:
// {
//   "customerId": ["1", "2", "3"], // Precise values inferred from the filter
//   "status": undefined,           // Cannot infer precise values for 'status'
// }
```

Arguments:
* **metadata** - The metadata of the entity being filtered.
* **filter** - The filter to analyze.
## getPreciseValues
Retrieves precise values for each property in a filter for an entity.


#### returns:
A promise that resolves to a FilterPreciseValues object containing the precise values for each property.


#### example:
```ts
const preciseValues = await where.getPreciseValues();
console.log(preciseValues);
// Output:
// {
//   "customerId": ["1", "2", "3"], // Precise values inferred from the filter
//   "status": undefined,           // Cannot infer precise values for 'status'
// }
```
## createCustom
Creates a custom filter. Custom filters are evaluated on the backend, ensuring security and efficiency.
When the filter is used in the frontend, only its name is sent to the backend via the API,
where the filter gets translated and applied in a safe manner.


#### returns:
A function that returns an `EntityFilter` of type `entityType`.


#### example:
```ts
class Order {
 //...
 static activeOrdersFor = Filter.createCustom<Order, { year: number }>(
   async ({ year }) => {
     return {
       status: ['created', 'confirmed', 'pending', 'blocked', 'delayed'],
       createdAt: {
         $gte: new Date(year, 0, 1),
         $lt: new Date(year + 1, 0, 1),
       },
     }
   },
 )
}
// Usage
await repo(Order).find({
 where: Order.activeOrders({ year }),
})
```


#### see:
[Sql filter and Custom filter](/docs/custom-filter.html)
[Filtering and Relations](/docs/filtering-and-relations.html)

Arguments:
* **translator** - A function that returns an `EntityFilter`.
* **key** - An optional unique identifier for the custom filter.
## entityFilterToJson
Translates an `EntityFilter` to a plain JSON object that can be stored or transported.


#### returns:
A plain JSON object representing the `EntityFilter`.


#### example:
```ts
// Assuming `Task` is an entity class
const jsonFilter = Filter.entityFilterToJson(Task, { completed: true });
// `jsonFilter` can now be stored or transported as JSON
```

Arguments:
* **entityDefs** - The metadata of the entity associated with the filter.
* **where** - The `EntityFilter` to be translated.
## entityFilterFromJson
Translates a plain JSON object back into an `EntityFilter`.


#### returns:
The reconstructed `EntityFilter`.


#### example:
```ts
// Assuming `Task` is an entity class and `jsonFilter` is a JSON object representing an EntityFilter
const taskFilter = Filter.entityFilterFromJson(Task, jsonFilter);
// Using the reconstructed `EntityFilter` in a query
const tasks = await remult.repo(Task).find({ where: taskFilter });
for (const task of tasks) {
  // Do something for each task based on the filter
}
```

Arguments:
* **entityDefs** - The metadata of the entity associated with the filter.
* **packed** - The plain JSON object representing the `EntityFilter`.
## fromEntityFilter
Converts an `EntityFilter` to a `Filter` that can be used by the `DataProvider`. This method is
mainly used internally.


#### returns:
A `Filter` instance that can be used by the `DataProvider`.


#### example:
```ts
// Assuming `Task` is an entity class and `taskFilter` is an EntityFilter
const filter = Filter.fromEntityFilter(Task, taskFilter);
// `filter` can now be used with the DataProvider
```

Arguments:
* **entity** - The metadata of the entity associated with the filter.
* **whereItem** - The `EntityFilter` to be converted.
## constructor
* **Filter**

Arguments:
* **apply**
## resolve
Resolves an entity filter.

This method takes a filter which can be either an instance of `EntityFilter`
or a function that returns an instance of `EntityFilter` or a promise that
resolves to an instance of `EntityFilter`. It then resolves the filter if it
is a function and returns the resulting `EntityFilter`.


#### returns:
The resolved entity filter.

Arguments:
* **filter** - The filter to resolve.
## toJson
* **toJson**



# API Reference - Sort

# Sort
The `Sort` class is used to describe sorting criteria for queries. It is mainly used internally,
but it provides a few useful functions for working with sorting.
## toEntityOrderBy
Translates the current `Sort` instance into an `EntityOrderBy` object.


#### returns:
An `EntityOrderBy` object representing the sort criteria.
## constructor
Constructs a `Sort` instance with the provided sort segments.

Arguments:
* **segments** - The sort segments to be included in the sort criteria.
## Segments
The segments of the sort criteria.
## reverse
Reverses the sort order of the current sort criteria.


#### returns:
A new `Sort` instance with the reversed sort order.
## compare
Compares two objects based on the current sort criteria.


#### returns:
A negative value if `a` should come before `b`, a positive value if `a` should come after `b`, or zero if they are equal.

Arguments:
* **a** - The first object to compare.
* **b** - The second object to compare.
* **getFieldKey** - An optional function to get the field key for comparison.
## translateOrderByToSort
Translates an `EntityOrderBy` to a `Sort` instance.


#### returns:
A `Sort` instance representing the translated order by.

Arguments:
* **entityDefs** - The metadata of the entity associated with the order by.
* **orderBy** - The `EntityOrderBy` to be translated.
## createUniqueSort
Creates a unique `Sort` instance based on the provided `Sort` and the entity metadata.
This ensures that the sort criteria result in a unique ordering of entities.


#### returns:
A `Sort` instance representing the unique sort criteria.

Arguments:
* **entityMetadata** - The metadata of the entity associated with the sort.
* **orderBy** - The `Sort` instance to be made unique.
## createUniqueEntityOrderBy
Creates a unique `EntityOrderBy` based on the provided `EntityOrderBy` and the entity metadata.
This ensures that the order by criteria result in a unique ordering of entities.


#### returns:
An `EntityOrderBy` representing the unique order by criteria.

Arguments:
* **entityMetadata** - The metadata of the entity associated with the order by.
* **orderBy** - The `EntityOrderBy` to be made unique.



# API Reference - SqlDatabase

# SqlDatabase
A DataProvider for Sql Databases


#### example:
```ts
const db = new SqlDatabase(new PostgresDataProvider(pgPool))
```


#### see:
[Connecting a Database](https://remult.dev/docs/quickstart#connecting-a-database)
## getDb
Gets the SQL database from the data provider.


#### returns:
The SQL database.


#### see:
[Direct Database Access](https://remult.dev/docs/running-sql-on-the-server)

Arguments:
* **dataProvider** - The data provider.
## createCommand
Creates a new SQL command.


#### returns:
The SQL command.


#### see:
[Direct Database Access](https://remult.dev/docs/running-sql-on-the-server)
## execute
Executes a SQL command.


#### returns:
The SQL result.


#### see:
[Direct Database Access](https://remult.dev/docs/running-sql-on-the-server)

Arguments:
* **sql** - The SQL command.
## wrapIdentifier
Wraps an identifier with the database's identifier syntax.
## ensureSchema
* **ensureSchema**

Arguments:
* **entities**
## getEntityDataProvider
Gets the entity data provider.


#### returns:
The entity data provider.

Arguments:
* **entity** - The entity metadata.
## transaction
Runs a transaction. Used internally by remult when transactions are required


#### returns:
The promise of the transaction.

Arguments:
* **action** - The action to run in the transaction.
## rawFilter
Creates a raw filter for entity filtering.


#### returns:
- The entity filter with a custom SQL filter.


#### example:
```ts
SqlDatabase.rawFilter(({param}) =>
     `"customerId" in (select id from customers where city = ${param(customerCity)})`
   )
```


#### see:
[Leveraging Database Capabilities with Raw SQL in Custom Filters](https://remult.dev/docs/custom-filter.html#leveraging-database-capabilities-with-raw-sql-in-custom-filters)

Arguments:
* **build** - The custom SQL filter builder function.
## filterToRaw
Converts a filter to a raw SQL string.


#### see:
[Leveraging Database Capabilities with Raw SQL in Custom Filters](https://remult.dev/docs/running-sql-on-the-server#leveraging-entityfilter-for-sql-databases)

Arguments:
* **repo**
* **condition**
* **sqlCommand**
* **dbNames**
* **wrapIdentifier**
## LogToConsole
`false` _(default)_ - No logging

`true` - to log all queries to the console

`oneLiner` - to log all queries to the console as one line

a `function` - to log all queries to the console as a custom format


#### example:
```ts
SqlDatabase.LogToConsole = (duration, query, args) => { console.log("be crazy ;)") }
```
## durationThreshold
Threshold in milliseconds for logging queries to the console.
## constructor
Creates a new SQL database.


#### example:
```ts
const db = new SqlDatabase(new PostgresDataProvider(pgPool))
```

Arguments:
* **sql** - The SQL implementation.
## end



# API Reference - SubscriptionChannel

# SubscriptionChannel
The `SubscriptionChannel` class is used to send messages from the backend to the frontend,
using the same mechanism used by live queries.


#### example:
```ts
// Defined in code that is shared between the frontend and the backend
export const notif = new SubscriptionChannel<{ coolInfo: string }>("notif");

// Backend: Publishing a message
notif.publish({ coolInfo: "Message coming from the backend" });

// Frontend: Subscribing to messages
notif.subscribe((message) => {
    console.log(`Something exciting happened: ${message.coolInfo}`);
});

// Note: If you want to publish from the frontend, use a BackendMethod for that.
```
 ---

 ### Use cases:

 #### A user _(Paul)_ wants to notify everyone _(Eric & Simona)_
 ```ts
 // shared code between the frontend and the backend
 export const notif = new SubscriptionChannel<{ from: UserInfo, msg: string }>("notif");

 // Frontend, Paul can call a BackendMethod to send his message
 NotificationContoller.send("Hello everyone!")

 // Backend
 export class NotificationContoller {
   @BackendMethod({ allowed: true })
   static async send(message: string) {
     notif.publish({ from: remult.user, msg: message });
   }
 }

 // Frontend: Eric & Simona can subscribe to messages
 notif.subscribe((message) => {
   if (message.from === remult.user) return;
   console.log(`Message from ${message.from.name}: ${message.msg}`);
 });
 ```

 #### A complexe chart that needs to be updated on multiple changes
 ```ts
 // shared code between the frontend and the backend
 export const chart = new SubscriptionChannel<{ kind: "pie" | "bar" | "line", data: number[] }>("chart");

 // Entity
 @Entity<Task>("tasks", {
   saved: async (e) => {
     if (e.completed) chart.publish({ kind: "pie", data: [1, 2, 3] });
   }
 })
 export class Task { ... }

 // Frontend: in the chart component, we can subscribe to messages
 chart.subscribe((message) => {
   console.log(`Chart updated: ${message.kind}`, message.data);
 });
 ```
## constructor
Constructs a new `SubscriptionChannel` instance.

Arguments:
* **channelKey** - The key that identifies the channel.
## channelKey
The key that identifies the channel.
## publish
Publishes a message to the channel. This method should only be used on the backend.

Arguments:
* **message** - The message to be published.
* **remult** - An optional instance of Remult to use for publishing the message.
## subscribe
Subscribes to messages from the channel. This method should only be used on the frontend.


#### returns:
A promise that resolves to a function that can be used to unsubscribe from the channel.

Arguments:
* **next** - A function that will be called with each message received.
* **remult** - An optional instance of Remult to use for the subscription.



# API Reference - generateMigrations

# generateMigrations
Generates migration scripts based on changes in entities.


#### see:
[Migrations](https://remult.dev/docs/migrations.html)

Arguments:
* **options** - Configuration options for generating migrations.
   * **entities** - An array of entity classes whose changes will be included in the migration.
   * **dataProvider** - The data provider instance or a function returning a promise of the data provider.
   * **migrationsFolder** - (Optional) The path to the folder where migration scripts will be stored. Default is 'src/migrations'.
   * **snapshotFile** - (Optional) The path to the file where the snapshot of the last known state will be stored. Default is 'migrations-snapshot.json' in the `migrationsFolder`.
   * **migrationsTSFile** - (Optional) The path to the TypeScript file where the generated migrations will be written. Default is 'migrations.ts' in the `migrationsFolder`.
   * **endConnection** - (Optional) Determines whether to close the database connection after generating migrations. Default is false.



# API Reference - migrate

# migrate
Applies migration scripts to update the database schema.


#### see:
[Migrations](https://remult.dev/docs/migrations.html)

Arguments:
* **options** - Configuration options for applying migrations.
   * **migrations** - An object containing the migration scripts, each keyed by a unique identifier.
   * **dataProvider** - The data provider instance or a function returning a promise of the data provider.
   * **migrationsTable** - (Optional) The name of the table that tracks applied migrations. Default is '__remult_migrations_version'.
   * **endConnection** - (Optional) Determines whether to close the database connection after applying migrations. Default is false.
   * **beforeMigration** - (Optional) A callback function that is called before each migration is applied. Receives an object with the migration index.
   * **afterMigration** - (Optional) A callback function that is called after each migration is applied. Receives an object with the migration index and the duration of the migration.



# API Reference - Async Hooks

# initAsyncHooks
Initializes and enables async context tracking for the server.

This should be called before handling any incoming requests or calling `withRemult()`.


#### example:
```ts
import { remult, repo, withRemult } from 'remult';
import { initAsyncHooks } from 'remult/async-hooks';

import { Task } from './entities/Task.js';

initAsyncHooks();

// Thx to the `initAsyncHooks` above,
// we have isolated async contexts with multiple `withRemult()`,
// without needing to initialize a `remultApi` all the time!
withRemult(async () => {
    remult.user = { id: '42' };
    repo(Task).find()
});

withRemult(async () => {
    remult.user = { id: '21' };
    repo(Task).find()
});
```



# API Reference - REST API Spec

# Entity Rest Api Breakdown

All entities automatically expose a rest API based on the parameters defined in its decorator.

The API supports the following actions (we'll use the `products` entity as an example, and a specific product with an id=7):

| Http Method | Description                                                                         | example         | requires       |
| ----------- | ----------------------------------------------------------------------------------- | --------------- | -------------- |
| GET         | returns an array of rows                                                            | /api/products   | allowApiRead   |
| GET         | returns a single row based on its id                                                | /api/products/7 | allowApiRead   |
| POST        | creates a new row based on the object sent in the body, and returns the new row     | /api/products   | allowApiInsert |
| PUT         | updates an existing row based on the object sent in the body and returns the result | /api/products/7 | allowApiUpdate |
| DELETE      | deletes an existing row                                                             | /api/products/7 | allowApiDelete |

## Sort

Add \_sort and \_order (ascending order by default)

```
https://mySite.com/api/products?_sort=price&_order=desc
```

## Filter

You can filter the rows using different operators

```
https://mySite.com/api/products?price.gte=5&price.lte=10
```

## Select

Use `_select` with a comma separated list of the fields you would like to select

### Filter Operators

| operator     | description           | example                                            |
| ------------ | --------------------- | -------------------------------------------------- |
| `none`       | Equal To              | price=10                                           |
| .ne          | Not Equal             | price.ne=10                                        |
| .in          | is in json array      | price.in=%5B10%2C20%5D _(url encoded - `[10,20]`)_ |
| .contains    | Contains a string     | name.contains=ee                                   |
| .notContains | Not contains a string | name.notContains=ee                                |
| .startsWith  | Starts with a string  | name.startsWith=ee                                 |
| .endsWith    | Ends with a string    | name.endsWith=ee                                   |
| .gt          | Greater than          | price.gt=10                                        |
| .gte         | Greater than or equal | price.gte=10                                       |
| .lt          | Lesser than           | price.lt=10                                        |
| .lte         | Lesser than or equal  | price.lte=10                                       |
| .null        | is or is not null     | price.null=true                                    |

- you can add several filter conditions using the `&` operator.

### Count

```
https://mySite.com/api/products?price.gte=10&__action=count
```

returns:

```JSON
{
  "count": 4
}
```

## Paginate

The default page size is 100 rows.

```
https://mySite.com/api/products?_limit=25
```

```
https://mySite.com/api/products?_limit=5&_page=3
```

:::tip
You can use it all in conjunction:

```
https://mySite.com/api/products?price.gte=5&price.lte=10&_sort=price&_order=desc&_limit=5&_page=3
```

:::



# Active Record & Mutable - EntityBase

# EntityBase
* **EntityBase**
## constructor
* **EntityBase**
## _
* **_**
## $
* **$**
## assign
* **assign**

Arguments:
* **values**
## delete
* **delete**
## isNew
* **isNew**
## save
* **save**



# Active Record & Mutable - IdEntity

# IdEntity
* **IdEntity**
## constructor
* **IdEntity**
## id
* **id**
## _
* **_**
## $
* **$**
## assign
* **assign**

Arguments:
* **values**
## delete
* **delete**
## isNew
* **isNew**
## save
* **save**



# Active Record & Mutable - EntityRef

# EntityRef
* **EntityRef**
## hasErrors
* **hasErrors**
## undoChanges
* **undoChanges**
## save
* **save**

Arguments:
* **options**
   * **select**
## reload
* **reload**
## delete
* **delete**
## isNew
* **isNew**
## wasChanged
* **wasChanged**
## wasDeleted
* **wasDeleted**
## getId
* **getId**
## getOriginalId
* **getOriginalId**
## toApiJson
* **toApiJson**
## validate
* **validate**
## clone
* **clone**
## subscribe
* **subscribe**

Arguments:
* **listener**
## error
* **error**
## repository
* **repository**
## metadata
* **metadata**
## apiUpdateAllowed
* **apiUpdateAllowed**
## apiDeleteAllowed
* **apiDeleteAllowed**
## apiInsertAllowed
* **apiInsertAllowed**
## isLoading
* **isLoading**
## fields
* **fields**
## relations
* **relations**



# Active Record & Mutable - FieldRef

# FieldRef
* **FieldRef**
## subscribe
* **subscribe**

Arguments:
* **listener**
## valueChanged
* **valueChanged**
## load
Loads the related value - returns null if the related value is not found
## valueIsNull
* **valueIsNull**
## originalValueIsNull
* **originalValueIsNull**
## validate
* **validate**
## error
* **error**
## displayValue
* **displayValue**
## value
* **value**
## originalValue
* **originalValue**
## inputValue
* **inputValue**
## entityRef
* **entityRef**
## container
* **container**
## metadata
* **metadata**



# Active Record & Mutable - getEntityRef

# getEntityRef
Retrieves the EntityRef object associated with the specified entity instance.
The EntityRef provides methods for performing operations on the entity instance.


#### returns:
The EntityRef object associated with the specified entity instance.


#### throws:
If throwException is true and the EntityRef object cannot be retrieved.


#### see:
[Active Record & EntityBase](https://remult.dev/docs/active-record)

Arguments:
* **entity** - The entity instance.
* **throwException** - Indicates whether to throw an exception if the EntityRef object cannot be retrieved.



# Active Record & Mutable - getFields

# getFields
* **getFields**

Arguments:
* **container**
* **remult**



# Introducing Remult: The Backend to Frontend Framework You Always Wanted

> March 14, 2023 | Noam Honig

# Introducing Remult: The Backend to Frontend Framework You Always Wanted

Application developers, as their name implies, like to develop applications––they ultimately care very little about frontend vs. backend, and really just want to deliver value to users.  Being an application developer myself, and very much like other application developers, one of the things that constantly drives my decision making when selecting tools and frameworks is the fact that I’m also quite lazy. 

My main objective is to be able to ship applications with as little effort as possible, and my pet peeve is silly repetitive, mechanical tasks that make me die a little inside every time I need to perform them. For example, I don’t like to have to remember to align things that don’t automatically align themselves, as one common example of a repetitive task that is completely superfluous.  I guess my trademark is that when I encounter challenges, I will always look for ways to automate a solution.  (Like the app I once built in the 90s to send a romantic text message to my girlfriend once a day––to overcome my own romantic shortcomings).

I've been building tools and frameworks to increase developer productivity most of my professional career.  This all started back in 2006, when I identified a need for modernizing applications created using a low-code generator, to C#.NET.  I decided to not only create a fully automated migration solution but more importantly, create a C# class library that would enable an equivalent speed of development that was previously made possible by using the low-code tool.

This was a very high bar, as developers that are used to working in low-code are also often the type that don’t really like the details or the bits and bytes of the internals.  A developer who is happy to use low-code tooling is essentially only looking to write code that gets a specific task done.  Being able to replicate this in a coding framework needed to provide as seamless and simple of an experience that they had until now––but with code.  

Hundreds of organizations have used Firefly’s migration solution, from fortune 500s and governments to small software houses. The C# library provided   is still in use today, enabling “low-code level”, highly productive application development, combined with the flexibility of code.  

The ability to efficiently ship full applications with a simple library, to me, felt like something that had to be portable and replicated to the modern web.  The wheels began to turn.

## What Brought Us Here

Like many other web developers, when Node.js came out, I was excited about the promise of backend to frontend that came with it, that finally we don’t have to learn two languages to build a full stack application.  Just the sheer mental switch between languages––for me it was C# on the backend and then Javascript on the frontend, and this always came with its toll of friction and context switch that could even be considered debilitating to my dev workflow.

Even with the possibility Node.js presented of enabling Javascript on both ends, still not many developers chose to do so. All of the best practices and learning resources continued to recommend using two separate approaches for backend and frontend, and a complete separation of tools, libraries and frameworks with very little sharing of code and patterns for frontend and backend.

This modus operandi of having two separate languages each with its own syntax and logic, creates the need for a lot of repetitive boilerplate, such as code to pull the data from the database (for every single application entity), code to expose entity CRUD operations as an API, with four, five or even six different routes per entity, methods for these routes, and these all would again get duplicated and reused hundreds of times, and each time further complicated. You get the idea.  

And this is just on the backend. 

Now on the frontend you have reverse code for this, you have code that takes these JSON responses and rebuilds objects out of these, for you to be able use them on the frontend.  Just trying to get data from the database to the users, but in the meantime, you need code to read the database, serialize the JSON, send it over a route, only to have to deserialize and query it on the frontend, just to get it in front of the user.  

This is all mechanical code that practically does nothing.  Where, eventually, all of this is repeatable.  

Wait, there’s more. Every API route needs to be able to fetch data, provide some sort of server-side paging, sorting and filtering, delete, insert, and update, all of these very generic actions are repeated over and over by all developers building full stack applications all the time in millions of lines of code.  

Now let’s talk about concerns that cross over from the frontend to the backend that get duplicated. Up until a couple of years ago the frontend and backend were at best sharing types, but there’s so much more to types than just strings or integers.  

Commons questions like: how do you serialize these from JSON and then to JSON? How do you validate them? Today, validations on the frontend and backend are operations that are completely separate.  Which begs the questions WHY?  Why should I have to remember (as a lazy developer mind you) to have to perform two separate validations on the frontend and the backend?

![Duplicate boilerplate code](./introducing-remult-part-1/boilerplate.png)

There’s also a cultural aspect with this dichotomy between frontend and backend code, where there needs to be such impeccable communication and alignment between the developers, that is almost an impossible feat.  At the end of the day,  all of those places are places of friction where things can go wrong, with two completely different developers maintaining the code.

## Enter Remult

Remember when I said that when I encounter a challenge, my first course of action is to try and automate it away?  I couldn’t fathom how in 2018 it still is not viable to be able to get the same code to run on the frontend and the backend.  I started toying with this idea to see if I could truly make this possible, improve my own productivity (and hopefully for other developers too)––from validations, to typing, through authentication and authorization, all of the typical code that’s constantly being duplicated.

### The Remult Backstory 

Remult started as a side project, without a name, and with a completely different (albeit noble) purpose.  My wife volunteered at a food bank, and as a result, I too was volunteered to participate in distributing food parcels to the needy.  One day, as I was driving to distribute the parcels, holding a paper with a list of addresses I found myself getting lost in places you don’t want to get lost, and I knew I had to build them an app to help volunteers navigate efficiently.  I knew I could solve a lot of friction in the process of delivering food parcels to the needy through code––which is what I do best, and I wanted to focus on building the actual application and its capabilities, and not the pieces that hold it together.

So I built an application for inventory and distribution of our local food bank in Even Yehuda, an application they could use to generate distribution lists for volunteer couriers, and for the couriers to be able to navigate to and report back on delivery. I wrote the app, and at the same time the framework as well, the very framework I wanted to have when building web applications.  One that would focus on the data flow from the backend database all the way through to the frontend framework (the framework of your choice––whether Angular, React, or Vue––it shouldn’t matter). 

![Food Bank App](./introducing-remult-part-1/food-bank-app.jpg)

Instead of having to go through the entire process described above of serializing objects for every HTTP call on the frontend, and then reversing the entire process back into JSON from the backend to the frontend––this framework now made it possible to query on the frontend, using objects, and then automated the entire process from the frontend to the backend and back again.  I finally had the framework I dreamed of that eliminates the need to write all of this boilerplate, repetitive, duct tape code over and over again.

With its growth and use, a colleague and I worked on the framework, invested in its ability to scale and its stability, improved its API that underwent several iterations, and added many features.  The application built upon this frameworkIt was quickly adopted by other food banks around Israel who often encountered similar challenges with parcel delivery.  Our application after its first year managed to help distribute 17,000 parcels from food banks around Israel.  We were quite proud of this achievement––we started feeling like our framework could possibly withstand the test of scale, but we had no idea what was to come next..  

## What COVID Taught us About Scale and Security

Then COVID hit––and lock downs cut people in need off from the entire world.  Suddenly, the need to distribute food to the elderly and disabled skyrocketed.  The demand grew from 17,000 parcels annually to 17,000 parcels a day.  The app was then contributed for free to municipalities, NGOs and even the IDF’s Home Front to enable better inventory, allocation and distribution of parcels around Israel.

Once the application was adopted by the IDF, it also underwent a battery of security testing––cyber and penetration testing, which leveled up its security significantly.  The backend to frontend framework, and the application built upon it that was supposed to be just an experiment, withstood the scale of half a million parcel distributions in 2020 alone, and since then has maintained a similar number and is only growing.  During COVID it was adopted by  multiple countries around the globe––from Australia, to the EU, USA, and South Africa––to respond to similar needs during the pandemic.  

This is the backbone upon which Remult was built and battle tested, with all of this running on a $16-a-month Heroku server.  

Once the pandemic was behind us, my co-creator and I realized we had learned a lot.  We understood the framework was robust and could scale, was aligned with security best practices, and delivered the promise of democratizing the ability to build full stack applications without all of the known friction.

We wanted to share this with the world. 

So we open sourced the framework, to enable other lazy developers like us to be able to invest their energy in writing excellent applications that deliver value to users, and not on repeatable, mechanical code that apparently actually **can be automated** and shared by the backend and frontend.

Check out [Remult](https://remult.dev), and if you like it, give it a star.  Let us know what you’d like to see next, and also feel free to contribute to the project.

In our next post, we’ll do a roundup of tools in the ecosystem looking to solve similar challenges though different approaches, and unpack where Remult fits in, and what it’s optimized for.


# SvelteKit - Tutorial - Go further / Extra

# SvelteKit

## Create a SvelteKit Project

To create a new SvelteKit project, run the following command:

```sh
npx sv@latest create remult-sveltekit-todo
```

During the setup, answer the prompts as follows:

1. **Which Svelte app template?**: ... `minimal` Project
2. **Add type checking with TypeScript?** ... Yes, using `TypeScript` syntax
3. **Select additional options**: ... We didn't select anything for this tutorial. Feel free to adapt it to your needs.
4. **Which package manager?**: ... We took `npm`, if you perfer others, feel free.

Once the setup is complete, navigate into the project directory:

```sh
cd remult-sveltekit-todo
```

## Install Required Packages and Remult

Install Remult and any necessary dependencies by running:

```sh
npm install remult --save-dev
```

## Bootstrap Remult

To set up Remult in your SvelteKit project:

1. Create your remult `api`

::: code-group

```ts [src/server/api.ts]
import { remultApi } from 'remult/remult-sveltekit'

export const api = remultApi({})
```

:::

2. Create a remult `api route`

::: code-group

```ts [src/routes/api/[...remult]/+server.ts]
import { api } from '../../../server/api'

export const { GET, POST, PUT, DELETE } = api
```

:::

## Final Tweaks

Remult uses TypeScript decorators to enhance classes into entities. To enable decorators in your SvelteKit project, modify the `tsconfig.json` file by adding the following to the `compilerOptions` section:

```json [tsconfig.json]
{
  "compilerOptions": {
    "experimentalDecorators": true // [!code ++]
  }
}
```

## Run the App

To start the development server, run the following command:

```sh
npm run dev
```

Your SvelteKit app will be available at [http://localhost:5173](http://localhost:5173).

Your SvelteKit project with Remult is now up and running.

# Extra

## Extra - Remult in other SvelteKit routes

To enable remult across all sveltekit route

::: code-group

```ts [src/hooks.server.ts]
import { sequence } from '@sveltejs/kit/hooks'
import { api as handleRemult } from './server/api'

export const handle = sequence(
  // Manage your sequence of handlers here
  handleRemult,
)
```

:::

## Extra - Universal load & SSR

To Use remult in ssr `PageLoad` - this will leverage the `event`'s fetch to load data on the server
without reloading it on the frontend, and abiding to all api rules even when it runs on the server

::: code-group

```ts [src/routes/+page.ts]
import { remult } from 'remult'
import type { PageLoad } from './$types'

export const load = (async (event) => {
  // Instruct remult to use the special svelte fetch
  // Like this univeral load will work in SSR & CSR
  remult.useFetch(event.fetch)
  return repo(Task).find()
}) satisfies PageLoad
```

:::

::: tip
You can add this in `+layout.ts` as well and all routes **under** will have the correct fetch out of the box.
:::

## Extra - Server load

If you return a remult entity from the `load` function of a `+page.server.ts`,
SvelteKit will complain and show this error:

```bash
Error: Data returned from `load` while rendering / is not serializable:
Cannot stringify arbitrary non-POJOs (data.tasks[0])
```

To fix this, you can use `repo(Entity).toJson()` in the server load function and `repo(Entity).fromJson()` in the .svelte file
to serialize and deserialize well the entity.

::: code-group

```ts [src/routes/+page.server.ts]
import { repo } from 'remult'
import type { PageServerLoad } from './$types'
import { Task } from '../demo/todo/Task'

export const load = (async () => {
  const tasks = repo(Task).toJson(await repo(Task).find())
  return {
    tasks,
  }
}) satisfies PageServerLoad
```

```svelte [src/routes/+page.svelte]
<script lang="ts">
  import type { PageData } from "./$types";
  import { Task } from "../demo/todo/Task";
  import { repo } from "remult";

  let { data }: { data: PageData } = $props();

  let tasks = repo(Task).fromJson(data.tasks);
</script>
```

:::

---

#### Since `@sveltejs/kit@2.11.0`, there is a new feature: [Universal-hooks-transport](https://svelte.dev/docs/kit/hooks#Universal-hooks-transport)

With this new feature, you can get rid of `repo(Entity).toJson()` and `repo(Entity).fromJson()` thanks to this file: `hooks.ts`.

::: code-group

```ts [src/hooks.ts]
import { repo, type ClassType } from 'remult'
import { Task } from './demo/todo/Task'
import type { Transport } from '@sveltejs/kit'
import { api } from './server/api'

// You can have:
// A/ a local entity array to work only these ones (like here)
//  or
// B/ import a global entity array that will be
//    shared between backend and frontend (not in ./server/api.ts)
const entities = [Task]

export const transport: Transport = {
  remultTransport: {
    encode: (value: any) => {
      for (let index = 0; index < entities.length; index++) {
        const element = entities[index] as ClassType<any>
        if (value instanceof element) {
          return {
            ...repo(element).toJson(value),
            entity_key: repo(element).metadata.key,
          }
        }
      }
    },
    decode: (value: any) => {
      for (let index = 0; index < entities.length; index++) {
        const element = entities[index] as ClassType<any>
        if (value.entity_key === repo(element).metadata.key) {
          return repo(element).fromJson(value)
        }
      }
    },
  },
}
```

```ts [src/routes/+page.server.ts]
import { repo } from 'remult'
import type { PageServerLoad } from './$types'
import { Task } from '../demo/todo/Task'

export const load = (async () => {
  // const tasks = repo(Task).toJson(await repo(Task).find()) // [!code --]
  const tasks = await repo(Task).find()
  return {
    tasks,
  }
}) satisfies PageServerLoad
```

```svelte [src/routes/+page.svelte]
<script lang="ts">
  import type { PageData } from "./$types";
  import { repo } from "remult";

  let { data }: { data: PageData } = $props();

  // let tasks = repo(Task).fromJson(data.tasks) // [!code --]
  let tasks = data.tasks
</script>
```

:::

## Extra - Svelte 5 & Reactivity

Remult is fully compatible with Svelte 5, Rune, and Reactivity.

To take full advantage of it, add this snippet:

::: code-group

```html [src/routes/+layout.svelte]
<script lang="ts">
  import { remult, Remult } from 'remult'
  import { createSubscriber } from 'svelte/reactivity'

  // To be done once in the application.
  function initRemultSvelteReactivity() {
    // Auth reactivity (remult.user, remult.authenticated(), ...)
    {
      let update = () => {}
      let s = createSubscriber((u) => {
        update = u
      })
      remult.subscribeAuth({
        reportObserved: () => s(),
        reportChanged: () => update(),
      })
    }

    // Entities reactivity
    {
      Remult.entityRefInit = (x) => {
        let update = () => {}
        let s = createSubscriber((u) => {
          update = u
        })
        x.subscribe({
          reportObserved: () => s(),
          reportChanged: () => update(),
        })
      }
    }
  }
  initRemultSvelteReactivity()
</script>
```

:::

Then you can use `$state`, `$derived` like any other places

::: code-group

```html [src/routes/+page.svelte]
<script lang="ts">
  // Prepare a new task
  let editingTask = $state(repo(Task).create())

  // Check if the form has empty fields
  let formHasEmpty = $derived(!editingTask || editingTask.title.length === 0)

  // Clone the task to edit
  const editTask = async (task: Task) => {
    editingTask = repo(Task).getEntityRef(task).clone()
  }
</script>
```

:::

### Focus on auth reactivity

Anywhere in your frontend code you can set `remult.user = xxx` and all remult auth reactivity will work (remult.user, remult.authenticated(), ...)

```ts
const logout = async () => {
  try {
    remult.user = await AuthController.signOut()
  } catch (error) {
    alert(error.message)
  }
}
```

If you want `remult.user` to be filled in SSR, here is the code:

::: code-group

```svelte [src/routes/+layout.svelte]
<script lang="ts">
  import { untrack } from 'svelte'
  import type { LayoutData } from './$types'

  interface Props {
    data: LayoutData
    children?: import('svelte').Snippet
  }

  let { data, children }: Props = $props()

  $effect(() => {
    // Trigger the effect only on data.user update
    data.user
    untrack(() => {
      remult.user = data.user
    })
  })

  // initRemultSvelteReactivity stuff
</script>

{@render children?.()}
```

```ts [src/routes/+layout.server.ts]
import { remult } from 'remult'

import type { LayoutServerLoad } from './$types'

export const load = (async () => {
  return { user: remult.user }
}) satisfies LayoutServerLoad
```

:::

And you can trigger this with :

```ts
import { invalidateAll } from '$app/navigation'

const logout = async () => {
  try {
    await AuthController.signOut()
    invalidateAll() // [!code ++] // This will trigger the layout.server.ts load function
  } catch (error) {
    alert(error.message)
  }
}
```

## Extra - Remote Functions

SvelteKit is introducing a new feature called [Remote Functions](https://svelte.dev/docs/kit/remote-functions). It's early, but we want to see how it integrates with Remult.

Here is the default doc example (zod & drizzle or valibot & prisma, ...):

```ts
import { error } from '@sveltejs/kit'
import { query } from '$app/server'
import * as v from 'valibot' // or zod, ... any standard schema library
import * as db from '$lib/server/database' // with drizzle, prisma, pg, ... any database library

export const getPost = query(
  z.string(), // Standard Schema
  async (slug) => {
    const [post] = await db.sql`SELECT * FROM post WHERE slug = ${slug}`
    if (!post) error(404, 'Not found')
    return post
  },
)
```

With remult library, you have both:

- the database layer
- the standard schema layer

So you can replace the previous code with this:

```ts
import { error } from '@sveltejs/kit'
import { query } from '$app/server'
import { standardSchema, repo } from 'remult'
import { Post } from '$lib/entities'

export const getPost = query(
  standardSchema(repo(Post), 'slug'), // Standard Schema
  async ({ slug }) => {
    const post = await repo(Post).findFirst({ slug })
    if (!post) error(404, 'Not found')
    return post
  },
)
```

We are excited to see how you will use it 🚀

::: tip
More info about [remult standard schema](/docs/standard-schema)
:::