Skip to content

Latest commit

 

History

History
1077 lines (761 loc) · 44.3 KB

File metadata and controls

1077 lines (761 loc) · 44.3 KB

All notable changes to this project will be documented in this file.

[3.4.0] - 2026-09-07

Live query / SSE resilience. The client no longer loses updates when the SSE stream dies while HTTP still works.

  • Each server-side live query carries a version, sent with every change and returned by the keep-alive. The client refetches the snapshot on any version gap, so a dead socket, a half-open socket or a missed message is recovered within one keep-alive
  • SseSubscriptionClient reconnects forever with backoff (was 4 tries), reconnects on visibilitychange / online / pageshow, and recreates a socket that stops delivering events for flags.sseStaleMs
  • liveQuery first next() no longer waits for the SSE connection
  • Server SSE ping every 15s (was 45s), exported as ssePingMs
  • New flags.sseStaleMs (40s), flags.liveQueryKeepAliveMs (30s), flags.liveQueryPollWhenStaleMs (1s)
  • SubscriptionListener.reconnect?() lets SubscriptionChannel subscribers refetch state after a dropped connection
  • LiveQueryChange has an internal { type: 'version', from, to } member, filtered out before reaching liveQuery listeners
  • Breaking for custom LiveQueryStorage: keepAliveAndReturnUnknownQueryIds returns { unknownQueryIds, versions } instead of string[]. The keep-alive route still accepts the old array body from older clients
  • SubscriptionClientConnection gained optional lastServerEvent and resume(force?); custom clients (Ably, ...) can ignore them
  • Fixed REST _select / find({ select }) serializing omitted fields through toApiJson, so dates and custom converters leaked as '' instead of being absent
  • REST docs fixes

[3.3.18] - 2026-08-30

  • Fixed ArrayEntityDataProvider storing omitted/undefined nullable fields as undefined instead of null, so filters like { date: null } missed rows inserted without a value

[3.3.17] - 2026-08-24

  • Fixed TypeError: Cannot delete property on client save when a field has includeInApi: false and the entity was subscribed (e.g. grid dirty tracking)

[3.3.16] - 2026-07-14

  • Added support for default values without an arrow function
  • Added type info in the field's function response - used for typing stuff :)

[3.3.15] - 2026-07-10

  • Added a Node built-in SQLite data provider (remult/remult-node-sqlite), using the native node:sqlite module (#1034).
  • Thanks to @linoch512 for their first contribution
  • groupBy now ignores orderBy fields that are not part of the group by (previously they were passed through to the database, producing an invalid grouped query on SQL Server / Postgres). The rest api additionally ignores orderBy fields that are not included in the api.

[3.3.14] - 2026-07-08

  • Fixed a memory leak related to usage of repo(x,y) with infinite different y

[3.3.13] - 2026-06-09

  • Fixed groupBy/aggregate with limit/page but no orderBy emitting OFFSET/FETCH without an ORDER BY, which is invalid on SQL Server. A grouped query now falls back to ordering by the group columns, and a pure aggregate skips paging entirely.
  • The query api action no longer leaks the items' paging into the aggregate, so the aggregate summarizes the whole filtered set.

[3.3.12] - 2026-06-01

  • Fixed issue with auto increment in ArrayEntityDataProvider where the dbname of the auto increment field was different than the member key

[3.3.10] - 2026-05-19

  • Improve Indexed db connection error further

[3.3.9] - 2026-05-15

  • Change Postgres Table Alter Autoincrement to Use Serial, by @jckwik - #968
  • Thanks to @jckwik for their first contribution
  • Improved handling of indexed db connection close etc...

[3.3.8] - 2026-05-12

  • Fixed issue with indexed db recovery after close (ios closes long open indexed db)

[3.3.7] - 2026-04-09

  • Reduced npm package size by > 50%

[3.3.6] - 2026-01-23

  • Added clear to indexed db database

[3.3.5] - 2026-01-14

  • #874 - fix: Ensure backend methods are included directly (openApi sveltekit)

[3.3.4] - 2026-01-12

  • #876 Relation should return undefined when includeInApi is false for its id field

[3.3.3] - 2025-12-30

  • #865 - fix paging syntax in group by for sql server
  • #864 - fixed missing transformations for min and max group by values
  • Added paged query result to internals (for now)

[3.3.2] - 2025-12-09

  • Expose DataProviderPromiseWrapper in internals

[3.3.1] - 2025-11-18

  • Doc update by @jycouet in #831
  • Light check if admin is here (demo app) by @jycouet in #834
  • #830 - changed update many to always use select none
  • #829 - fixed issue with insert & knex & autoIncrement columns
  • Added support for select:'none' also to save
  • Fixed issue with where:'all'

[3.3.0] - 2025-11-09

  • #820 - option to eliminate update/insert result to improve performance.
    repo(Task).Insert({ id: 1, name: 'test' }, { select: 'none' })
  • Added option for deleteMany({where:'all'}) and updateMany({where:'all',set:{ status:0 }})
  • Fixed a bunch if issues around ValueConverter.DateOnlyString

[3.2.3] 2025-10-25

  • Fix Backend method issue #890

[3.2.2] 2025-9-30

  • Updated remult admin to manage allowNull fields

[3.2.1] 2025-8-18

  • Export EntitySelectFields type

[3.2.0] 2025-8-18

  • Added support for select in find, now you can select which fields will be part of the query and part of the result.
    await repo(Task).find({ select: { id: true, title: true } })
  • Thanks to @delebash for their first contribution

[3.1.2] 2025-8-03

  • Minor fix for standardSchema - require an object.
  • Thanks to @Nipodemos for their first contribution to the docs

[3.1.1] 2025-7-30

[3.1.0] 2025-7-29

  • Fix by @LazyShpee for initAsyncHooks without remultApi
  • Added support for express 5
  • Added support for nuxt 4
  • removed remult dependencies:
    • reflect-metadata
    • uuid
    • @paralleldrive/cuid2
  • Minimum node version is now 18 (with --experimental-global-webcrypto flag) or 20 (without flag)
  • We are introducing @Fields.id() field (using crypto.randomUUID() under the hood)
    • @Fields.uuid() is now deprecated, use @Fields.id() instead (uuid is the default id factory)
    • [BREAKING] Removed @Fields.cuid() - use @Fields.id() instead and change the idFactory to your preferred id algorithm.

How to migrate from @Fields.cuid() to @Fields.id()

You have 2 options:

A/ Update globally @Fields.id() to use cuid algorithm

First, install the @paralleldrive/cuid2 package:

npm install @paralleldrive/cuid2

Then, globally, in a shared code file:

import { createId } from '@paralleldrive/cuid2'
import { Fields } from 'remult'

Fields.defaultIdFactory = () => createId()

Finally, replace @Fields.cuid() with @Fields.id()

B/ Create your own cuid Field

First, install the @paralleldrive/cuid2 package:

npm install @paralleldrive/cuid2

Then, create your own cuid Field:

import { createId } from '@paralleldrive/cuid2'
import { Fields } from 'remult'

export function MyFields_cuid<entityType = any>(
  ...options: FieldOptions<entityType, string>[]
) {
  return Fields.id<entityType>({ idFactory: createId }, ...options)
}

Finally, replace @Fields.cuid() with MyFields_cuid()

[3.0.6] 2025-7-6

  • Added a label option for field and entity that'll gradually replace caption
  • Added modules to remultApi options.
  • Added remult.context.headers to access the request headers in a framework-agnostic way.
  • Added D1 Support by (@taivo) Big thanks to @taivo for his first contribution

[3.0.5] 2025-6-6

  • Fixed a performance issue added in 3.0.0
  • #719 Export initAsyncHooks for use of withRemult in non API projects Big thanks to @LazyShpee for his first contribution

[3.0.4] 2025-5-26

  • Fixed issue where cases when multiple $ne or $nin were used with rest data provider and the value 0 - the 0 value would sometime not be sent to the server

[3.0.3] 2025-5-23

  • Few doc updates by @jycouet in #704
  • add removeItem method to JsonEntityIndexedDbStorage by @TGlide in #703
  • 🚧 UPDATE: sveltekit data is now always returning application/json by @jycouet in #706
  • Fix undefined error in TestApiDataProvider with multiple relations

[3.0.2] 2025-5-13

  • Update DuckDB adapter to use new @duckdb/node-api package - #700 Big thanks to @jc955 for his first contribution

[3.0.1] 2025-5-9

  • #697 - escape backtick in migrations code Big thanks to @fapspirit for his first contribution

[3.0.0] 2025-5-7

  • Unified the function name used to setup remult api to remultApi (Instead of remultExpress etc...)
  • Added a dataProvider function to EntityOptions that allows you to select a dataProvider per entity.
  • Admin UI:
    • you can now add custom headers requests (key: value format)
    • In diagram, you can visualize ToOne relations with the color of the entity on the left.
    • add requireAuthToken to admin options to open settings dialog to set the bearer token directly.
    • add disableLiveQuery to admin options to control if live query is used. (can be overwritten by local storage settings)

[2.7.34] 2025-4-29

  • Added support for sql expression based entity to knex data provider

[2.7.33] 2025-4-5

  • Fixed bug with API Update of null with dateOnly
  • Fixed admin to show json editor also for arrays

[2.7.32] 2025-3-18

  • Added subscribeAuth to remult to support reactivity
  • Admin ui:
    • Fixed issue where json editor was not working when the json field was an array
    • Fixed issue where json field did not trigger the change detection (color green)

[2.7.31] 2025-3-9

  • ValueConverters.Number.fromInput(null) now returns null (was undefined before).

[2.7.30] 2025-3-2

  • Fixed where containing a $not from api to work in addition with other filters.
  • More fixes to remult admin

[2.7.29] 2025-2-9

  • Fixes to remult admin
  • Improved error in case if undefined in getEntityRef

[2.7.28] 2025-1-13

  • fix: sqlite - index already exists by @olragon in #599 Big thanks to @olragon for his first contribution

[2.7.27] 2025-1-6

  • Fixed issue with turning on admin breaks routing in some cases

[2.7.25] 2025-1-1

  • Fixed admin to work with authorization token as well
  • Moved version decimal point to better reflect remult's stability and use in production app.

[0.27.24] 2024-12-11

  • Fixed issue where setting a value to undefined, caused an invalid update statement - update "tasks" set where "id" = $1 and an error: error: syntax error at or near "where"
  • Fixed issue where find options object was changed when sent to find method
  • Fixed an issue where group by was accessible even if allowApiRead was not - this did not affect apiPrefilter

[0.27.23] 2024-11-23

  • Added min, max and range validators by @YonatanKra
  • Quality of life improvements to admin by @jycouet & @ermincelikovic
    • In the office hour with @ermincelikovic (and cursor) we :
    • reduce the column size of numbers & align right
    • manage keyboard navigation in the grid
    • manage shortcuts
    • CTRL+Enter => Save the row
    • CTRL+Esc => Cancel the tow
    • CTRL+SHIFT+Enter => Save all rows
    • CTRL+SHIFT+Esc => Cancel all rows
  • Added EntityError - now when insert/update etc... fail they throw this specific error.
  • Log queries if they are greater than equals the threshold by @arikfr in #571
  • Fixed an issue with decorators and optional null field
  • fixed issue with aggregate in query
  • Fixed issue with subscribe to entity changes and relations
  • Remult create adjusted for Svelte 5 by @jycouet

[0.27.22] 2024-11-08

  • Improved support for sveltekit ssr. To configure:
    • To enable remult across all sveltekit route

      // src/hooks.server.ts
      import { api } from './server/api'
      export const handle = api
    • 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

      // 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 to fetch data on server side page load
        remult.useFetch(event.fetch)
        return repo(Task).find()
      }) satisfies PageLoad

[0.27.21] 2024-10-28

  • Added upsert method:
    The upsert method allows inserting or updating an entity in a single operation. If an entity matching the where condition is found, it is updated; otherwise, a new entity is created. This can be used for a single entity or for batch operations with an array of options.

    Example:

    // Single entity upsert
    await taskRepo.upsert({
      where: { title: 'task a' },
      set: { completed: true },
    })
    
    // Batch upsert
    await taskRepo.upsert([
      { where: { title: 'task a' }, set: { completed: true } },
      { where: { title: 'task b' }, set: { completed: true } },
    ])
  • Now you can get data and aggregate info with a single request using the query method:

    const result = await repo
      .query({
        where: { completed: false },
        pageSize: 50,
        aggregates: {
          sum: ['salary'],
          average: ['age'],
        },
      })
      .paginator()
    // Accessing the items from the first page
    console.table(result.items)
    // Accessing the aggregation results
    console.log(result.aggregates.salary.sum) // Total salary sum
  • Added TestApiDataProvider to use in unit tests that test api rules. see tutorial

  • Fixed that values that are not included will not exist in the resulting object (previously they existed with value undefined)

  • Fixed that relations that were not included, will not be enumerable in the resulting object (previously they were only set to undefined)

  • Fixed serverExpression to run whenever we're not using a proxy data provider (for example RestDataProvider)

  • Fixed issue with updateMany where the set had ValueListType or relation.

  • Fixed issue when updating relation id and relation in the same update, the last one will win

  • Fixed makeTitle to handle all caps text

  • Added experimental api for sqlRelations & sqlRelationsFilter - see Sql Relations

[0.27.20] 2024-10-16

  • Added Origin IndexedDb Storage to store entities in the frontend:

    const db = new JsonDataProvider(new JsonEntityIndexedDbStorage())
    console.table(await repo(Task, db).find())
  • Fixed issue with required validation and relations

[0.27.19] 2024-09-26

  • Fixed issue with stackblitz async_hook replacer

[0.27.18] 2024-09-24

  • Added remult.initUser that initializes the frontend remult with the user based on the backend
  • Fixed issue with dual call to initRequest in some cases

[0.27.16] 2024-09-21

  • Added support for customFilter defined in base classes

[0.27.14] 2024-09-20

  • A few tweaks by @jycouet in #515
  • migrate to remult kit by @Yedidyar in #519

[0.27.13] 2024-09-16

  • fixed issue with null first and group by
  • fixed an error where from json returned a row that didn't have an id and could cause problems
  • fixed double init request in cases where withRemult accidentally wraps remult server

[0.27.12] 2024-09-05

  • added $not to value comparison: {where:{id:{ $not:1 }}}} for improved readability
  • removed group option from aggregate
  • Added unique id validations to all databases
  • Verified that all databases add missing columns on ensureSchema
  • Removed the deprecated behavior where if no entities array was sent to remult server, all entities were served
  • Removed the deprecated web sql data provider, since no browsers support it - us the OpfsEntityDataProvider instead
  • Changed id signature in EntityOptions to also allow id:'code' & id:['company','code'] for compound id columns
  • Fix to remult admin

[0.27.11] 2024-09-04

  • Potential breaking change change the http status code of exceptions thrown in backend method from 500 to 400

[0.27.10] 2024-09-03

  • Fix for minor typing issue regarding field | null | undefined

[0.27.9] 2024-09-02

  • Fix for minor issue in knex

[0.27.8] 2024-09-02

  • More great improvements to remult admin by jycouet
  • Added groupBy & aggregate to Repository
    repo(Employee).groupBy({
      group: ['country', 'city'],
      sum: ['salary'],
      where: {
        salary: {
          $gt: 2000,
        },
      },
    })
    Checkout this example video

[0.27.6] 2024-08-28

  • Improvement to remult admin + support for bearer token in admin
  • Fix to recursive sql expression
  • Added support for backend method without a transaction using transactional:false
  • Fixed live query, to update the subscribers asynchronously

[0.27.5] 2024-08-23

  • #474 When using knex, an id column with auto-increment that is not named id in the db gave an error

[0.27.3] 2024-08-14

  • Changed RelationOptions to be an extendable interface and not a type

[0.27.2] 2024-08-07

  • Added request to remult.context that'll be available through the request lifecycle - to access it please extend the RemultContext type as follows
    import type express from 'express'
    declare module 'remult' {
      export interface RemultContext {
        request?: express.Request
      }
    }

[0.27.0] 2024-08-01

API BREAKING CHANGE - Improved Typescript typing

Typescript version 5.4 included many changes that cause unknown & any to behave differently breaking existing code for some project.

In this version we reviewed the external api and made sure that it matches TS 5.4 while still supporting older version of TS (4.6)

Theses change are likely to cause build errors in existing projects, but in most cases these errors represent potential bugs that should be addressed. Here's the list of significant changes:

  • findFirst, findOne and findId can return undefined when the row is not found, if you're sure that the row exists, add a ! after it, for example:
    let p = await repo(Person).findId(7) // p will be Person | undefined in the new version
    let q = (await repo(Person).findId(7))! // p will be Person
  • Decorators that use entity, now require to define the entity in the generic definition. Previously you could have the following code:
    @Fields.string({
      validate: task => task.title.length > 2
    })
    title=''
    Now, that code will return an error that title is not a member of unknown. To fix that add the Entity generic definition:
    @Fields.string<Task>({
      validate: task => task.title.length > 2
      title = ''
    })
  • FieldMetadata.key was changed from string to keyof entityType making it easier to traverse the object.
  • error in EntityRef, FieldRef and ControllerRef can be undefined when there is no error
  • Change = any to = unknown in most generic definitions

[0.26.23] 2024-07-30

  • Fixes and improvements to the admin panel

[0.26.22] 2024-07-19

  • fixed issue with prevent default and insert

[0.26.21] 2024-07-11

  • Fixed a bug with startsWith and endsWith worked like contains

[0.26.20] 2024-07-10

  • Added support for $not, $startsWith & $endsWith

[0.26.19] 2024-07-08

  • Fixed issue with recursive sqlExpression call for field

[0.26.18] 2024-07-07

  • Fixed an issue with sqlExpression without aliases - now remult automatically adds an alias in select, but not in order by or where.

[0.26.17] 2024-07-06

  • Added support for DuckDB

[0.26.16] 2024-07-04

  • Many improvements to remult-admin
  • HUGE thanks to jycouet & celikovic for their amazing work on remult-admin

[0.26.15] 2024-06-28

  • docs - svelte tuto improvement by @jycouet in #458
  • Fix #460

[0.26.14] 2024-06-18

  • Fixed typescript error with KnexDataProvider
  • fixed issue where migrate didn't work in commonjs
  • Bump mysql2 from 3.9.7 to 3.9.8 by @dependabot in #445
  • fix auth.ts import for Next.js tutorial by @LegitPanda in #446
  • Update example-apps.md by @ikx94 in #447
  • Bump @azure/msal-node and tedious by @dependabot in #450
  • Bump braces from 3.0.2 to 3.0.3 by @dependabot in #449
  • Bump braces from 3.0.2 to 3.0.3 in /examples/angular-todo-fastify by @dependabot in #451
  • docs: improve swagger-ui integration guide page with nextjs specific info by @kckusal in #448

New Contributors

  • @LegitPanda made their first contribution in #446
  • @ikx94 made their first contribution in #447
  • @kckusal made their first contribution in #448

[0.26.13] 2024-05-22

  • fix validators with args type-check error in ts 5.4

[0.26.12] 2024-05-16

  • Fixed an issue with stack overflow when calling withRemult from within getUser - relevant to next auth - session hook
  • The "static" withRemult will now use the dataProvider provided in the remultServer options by default
  • The "static" withRemult now supports promise of data provider etc...
  • Changed json storage to save json in a non formatted way (condensed), and added a formatted option to control it. By default JsonFile storage is formatted
  • Improved error handling in request lifecycle

[0.26.11] 2024-05-13

  • Fixed error in sqlite with reserved column names such as order etc...
  • #427 - Changed the retry on error 500, to 4 times instead of 50 or infinite that was before.
  • Potential breaking change #426 - Fixed to not trigger all relations to one load before saving and around read write json
  • Fixed error when id was not found in ArrayEntityDataProvider to include the entity name
  • Fixed filterToRaw to use the current database wrapIdentifier when none is provided.
  • Fixed endless retry on error 500 - now it'll retry 4 times 500ms apart.
  • Fixed error when sql expression sometimes translated wrongfully to a recursion error
  • Added support for Turso db

[0.26.10] 2024-05-02

  • Fix order by error with multiple id columns

[0.26.8] 2024-05-01

  • Added support for sqlite3 that runs on stackblitz
  • Fixed issues with knex when id columns are being updated
  • Fixed issues with mongo when id columns are being updated

[0.26.7] 2024-05-01

  • Fixed issue with id being empty in some cases in the saved hook
  • Added describeEntity and describeBackendMethods for better decorator-less support

[0.26.6] 2024-04-29

  • Minor fix to async_hooks fallback for running on stackblitz

[0.26.5] 2024-04-28

  • Breaking change - changed the api of updateMany to receive a set option, instead of second parameter for the set
  • Fixed primary key was not created for entities that had more than one id column using knex or postgres
  • Fixed issue where dbNamesOf in entity sqlExpression did not work

[0.26.4] 2024-04-24

  • getValueList now supports @Fields.literal & @Fields.enum (on top of ValueListType)

[0.26.3] 2024-04-22

  • Fixed issue with delete on Hono with session middleware
  • Fixed an issue with admin not working with Hono@4.2

[0.26.2] 2024-04-21

[0.26.1] 2024-04-18

  • Fixed issue where 404 return an error - forbidden instead of not found
  • Fixed an issue where preventDefault in deleting did not work

[0.26.0] 2024-04-08

Features

  • Added support for migrations. See Migrations.
  • Added an error hook to RemultServerOptions that is called whenever there is an error in the API lifecycle. See RemultServerOptions.
  • Added ForbiddenError to the API, you can throw it anywhere in the request lifecycle to display a forbidden 401 error.
  • Added @Fields.literal and @Fields.enum.
  • Added support for better-sqlite3 without knex, see Connection a Database.
  • Added support for bun:sqlite #387.
  • Added a generic implementation for sqlite that can be easily extended to any provider.
  • Added apiPreprocessFilter and backendPreprocessFilter, see access control.
  • Added a way to analyze filter and query it - Filter.getPreciseValues, which returns a FilterPreciseValues object containing the precise values for each property. see access control.
  • Added an exception when calling updateMany or deleteMany without a filter - to protect against accidental deleting/updating all data.
  • Added updateMany and deleteMany to OpenAPI (swagger) & graphql

Improvements

  • Added validation for @Fields.number & Fields.integer that the value is a valid number.
  • Added "basic" supports for environments where async hooks doesn't work well - mostly for web based dev machines.
  • Improved the API of rawFilter so it can now return the SQL where to be added to the command. see Leveraging Custom Filters for Enhanced Data Filtering
  • KnexDataProvider now supports all execute and createCommand and can be used with any SqlDatabase functionality.
  • Changed postgres schema builder to use timestamptz instead of timestamp.
  • Changed the default storage of @Fields.object to text (varchar max) instead of string 255 in knex and sqlite.

Documentation Updates

Bug Fixes

  • Fixed an issue with entity ids that included date.
  • Fixed an issue with repo(Entity,dataProvider) - where saving wasn't fired because of wrong isProxy inference.
  • Fixed an issue with chaining of validators that in some cases caused a validator to be overwritten.
  • Fixed ValueConverters Number fromInput handle 0 as a valid value.

Breaking Changes

  • Changed the signature of updateMany and deleteMany to require a where parameter: repo(Task).delete({ where: { completed: true } }).
  • Changed the signature of getDb to receive DataProvider as a parameter instead of Remult.
  • Changed the POST REST API queries to include the filter under the where key in the body - previously, it included the filter as the body itself.

New Contributors

  • @eylonshm made their first contribution in #376
  • @daan-vdv made their first contribution in #397

[0.25.8] 2024-04-05

  • Fixed issue with typing when skipLibCheck: false

[0.25.7] 2024-03-21

  • Fixed typing issue with validators and typescript 5.4
  • Added deleteMany and updateMany
  • When insert is called in the front-end with an array of items, a single POST call is made to the server
  • Renamed addParameterAndReturnSqlToken to param. addParameterAndReturnSqlToken will be deprecated in future versions
  • Default number storage in knex, previously was decimal(8,2) now, decimal(18,2)
  • Fixed issue where exception throws in initRequest or getUser caused server to crash, instead of return a bad request error
  • Changed required to allow 0 as a value - so only null, undefined and empty strings are considered invalid for a required field
  • Fixed an issue where backendPrefilter was not applied to id based update, save or delete in the backend

[0.25.6] 2024-03-17

  • Added support for orderByNullsFirst in PostgresDataProvider to change the default postgres behavior where nulls are last
  • Added support for tableName option argument for dbNamesOf that'll add the table name to each field Before:
    const orders = await dbNamesOf(Order)
    return `(select count(*) from ${orders} where ${orders}.${orders.id}=1)
    Now:
    const orders = await dbNamesOf(Order, { tableNames:true })
    return `(select count(*) from ${orders} where ${orders.id}=1)
  • improved dbNamesOf of to use by default the wrapIdentifier of the current data provider if no wrap identifier was provided
  • Added support for using dbNamesOf in an sql expression for that same entity
  • Improved performance of dbNamesOf
  • Added support for Hono web framework
  • Improved support for Mono repo scenario #355
  • Added withRemult to next js page router
  • Fixed custom message to some validators (in etc...)
  • Improved support for union string fields

[0.25.5] 2024-02-11

  • Added admin option to servers, enabling the /api/admin route with a built in entity explorer
  • Fixed multiple issues with GraphQL and relations
  • Improved support for esm/cjs in same process scenario
  • Enabled json storage type for mysql & mysql2 knex adapters
  • Fixed issue in case of missing reflect-metadata
  • Added a recommended way to use remult in sveltekit using api/[...remult]/+server.ts route instead of a hook
  • Added ArrayEntityDataProvider to the external api

[0.25.4] 2024-01-15

  • Fixed issue where a new row that was saved, changed again and saved again - provide wrong isNew:true value for field validate

[0.25.3] 2024-01-15

  • Fixed #320, dbReadonly columns are not created in the db

[0.25.2] 2024-01-12

  • Fix the defaultMessage of validators
  • Added Validators.minLength

[0.25.1] 2024-01-11

  • Fixed issue where defaultGetLimit caused issues with include queries

[0.25.0] 2024-01-10

Improvement for validators

  • Added required as a FieldOption
  • Added validation for maxLength in StringFieldOptions
  • Added the following validators to the Validators class:
    • regex
    • email
    • url
    • in
    • notNull
    • enum
    • relationExists,
    • maxLength
  • Added support for return value for validations - true || undefined are valid, string will provide the message. For example:
    @Fields.string({
      validate:(task)=> task.title.length > 5 || "too short"
    })
  • Added the valueValidator helper function:
    @Fields.string({
      validate: valueValidator(value => value.length > 5)
    })
  • Added helper functions to create validators, createValueValidator, createValueValidatorWithArgs, createValidator & createValidatorWithArgs
  • Changed signature of FieldOptions.validate the receive ValidateFieldEvent object as the second parameter instead of FieldRef
  • Updated Signature of required and unique based on api change
  • Adjusted the unique validator to only run on the backend

New Frontend Data Providers

  • Added Origin Private File System Storage to store entities in the front end
    const db = new JsonDataProvider(new JsonEntityOpfsStorage())
    repo(Task, db)
      .find()
      .then((tasks) => console.table(tasks))
  • Added SqlJsDataProvider for use with front end sqlite implementation sql.js
    const db = new SqlDatabase(
      new SqlJsDataProvider(initSqlJs().then((x) => new x.Database())),
    )
    repo(Task, db)
      .find()
      .then((tasks) => console.table(tasks))

Other

  • Added clone to EntityRef
  • Fixed issue where findOne didn't work
  • Fixed issue where exception XXX is not a known entity, did you forget to set @Entity() or did you forget to add the '@' before the call to Entity? was thrown in cases where multiple instances of remult were in memory
  • Issue #314 resolved by @itamardavidyan in #315

[0.24.1] 2023-12-30

  • Improved JsonDataProvider to support promise for load and save, useful in all sorts of cases
  • Fixed issue with ESM on NodeJS - Module '"remult/postgres"' has no exported member 'createPostgresDataProvider'.

[0.24.0] 2023-12-29

Changed

  • BREAKING CHANGE: PostgresDataProvider: Column & table names are now quoted (e.g., "firstName") to enforce specific casing in PostgreSQL.
    • To revert to the old (version < 0.24) case-insensitive identifiers, set caseInsensitiveIdentifiers: true when using createPostgresDataProvider.

Added

  • ESM support for NodeJS
  • Support for nuxt Fullstack framework
  • Support for the sqlExpression field option in entities using the knex data provider.
  • schema parameter to PostgresDataProvider & createPostgresDataProvider.
  • findOne method in Repository with a unified options parameter for simplicity.
  • withRemultAsync function in remultExpress for contexts outside the normal request lifecycle.
  • withRemult function for obtaining a valid remult context in server scenarios.
  • Inclusion of EntityMetadata in CaptionTransformer.transformCaption method.
  • dbName attribute in EntityMetadata & FieldMetadata.
  • wrapIdentifier optional parameter in dbNamesOf function.
  • dbNames as an optional parameter in the filterToRaw method of SqlDatabase.
  • wrapIdentifier method in SqlDatabase for wrapping identifiers before sending to the database.

Deprecated

  • getDbName method in EntityMetadata & FieldMetadata (to be removed in future versions).

Removed

  • run method from Remult.

Renamed

  • withRemultPromise to withRemultAsync in RemultServer.

[0.23.6] 2023-12-26

  • Fixed issue where delete by id on the backend, didn't go through the deleting hook

[0.23.5] 2023-12-23

  • Fixed toOne relation filter null for non nullable fields to work
  • Fixed toOne relation filter on $id:0 failed to work
  • Fixed wrongful loading of toMany relation on api with defaultIncluded

[0.23.4] 2023-12-20

  • Fixed Live query to also work in init api #306

[0.23.3] 2023-12-19

  • Added support for notContains filter option

[0.23.1] 2023-12-12

  • Fixed case insensitivity in contains for mongo db

[0.23.0] 2023-12-11

  • Added Relations - see Relations

  • Added LifecycleEvent info for saving,saved,deleting,deleted - see Entity Lifecycle Hooks

  • Saving, Saved, Deleting, Deleted all run only on the backend now

  • include in api now supports expressions that use the current row

    • Breaking change - instead of if(repo.fields.name.includedInApi) you now need if(repo.fields.name.includedInApi(instance))
  • Changed the way an entity id is defined see Entity id's doc Example:

    @Entity<OrderDetails>("orderDetails", { id: { orderId: true, productCode: true } })
  • added repo function which is A convenient shortcut function to quickly obtain a repository for a specific entity type in Remult.

    await repo(Task).find()
  • Added support for (Hapi api server)[https://hapi.dev/]

  • Fixed exception with toRawFilter

  • Fixed json db to support db names

  • Fixed issue with sort result after live query

  • Fix issue with compound id on middleware based servers

  • Added with remult for sveltekit for usage before the remult hook

  • Fixed issue with requireId not respecting in statement #290

  • findId was changed to no longer use cache by default

[0.22.12] 2023-11-26

  • #297 - Crash on ensure schema failure

[0.22.11] 2023-11-23

  • Improved support for Mongo ObjectId field type #295

[0.22.10] 2023-11-17

  • Fixed issue with repo.validate without specifying fields

[0.22.9] 2023-10-06

  • Fixed issue with Entity Backend Method and fields with allow api false #255

[0.22.8] 2023-09-27

  • Fixed an issue with rest call that had both and & or
  • Fixed an issue regarding the usage of ManyToOne fields as part of the id

[0.22.7] - 2023-09-05

  • Fixed max stack reached in case of reference to self
  • Improved graphql one to many relations
  • Fixed live-query issue with complex filters
  • Refactored tests to use vitest, and latest typescript version
  • Fixed issue with postgres schema builder
  • Fixed schema build to support table name with schema name
  • Cleaned up code and removed angular dependency

[0.22.6] - 2023-08-10

  • Implemented $contains for mongo
  • Implemented contains for graphql

[0.22.5] - 2023-08-09

[0.22.4] - 2023-08-03

  • Fixed an issue where an update with only a few fields, would update all other fields to their default values.

[0.22.3] - 2023-08-02

  • Fixed an issue with the many-to-one relation where the 'many' table did not store the ID as a string in cases where the 'one' table's ID column was not an integer
  • Added tests for MariaDB and fixed issues

[0.22.2] - 2023-07-30

  • Fixed #216 wrong date type saved on update

[0.22.1] - 2023-07-25

  • Fixed issue #215 support for mongo without transactions

[0.22.0] - 2023-07-16

  • Added ToJson and FromJson methods the the Repository object. These are extremely useful in the context of SSR (next etc...) where you need to send plain json over the wire, but still want to have dates and other cool stuff in your app
  • Fixed an issue with the many-to-one relation where the 'many' table did not store the ID as an 'integer' in cases where the 'one' table's ID column was an integer
  • Fixed issue where using displayValue or validate on a spread object, marked it as new, and always triggered a post call
  • Added Remult.run
  • isBackend will return true or false based on dataProvider.isProxy equal false or runningOnServer member
  • Backend method will call backend based on isBackend method,
  • Replaced deprecated cuid with paralleldrive/cuid2
  • Fixed an issue where when getDb was called without a remult parameter, it wouldn't use the default remult
  • Fixed liveQuery's apply changes to also support state that it's initial value is undefined.
  • Typescript 5 style decorators are now supported in development, but to deploy you still need experimentalDecorators .
    • Also, the decorators now do type checking, so if you put @Fields.string() on a number, it'll give you an error
    • And - no longer need for the Generics in the decorators setting.
      • @Entity<Task>(...) is now @Entity(...)
      • @Fields.string<Task>(...) is now @Fields.string(...)
    • Why didn't we implement typescript 5 decorators in runtime? the implementation for that is not yet fully supported with tools such as esbuild etc... so implementing it is trying to hit a moving target. At this time we recommend using experimentalDecorator:false for development, to get the typing, but experimentalDecorator:true for deploying and functionality.
  • Added 404 on missing route for next app router - issue #211
  • Fixed an issue where live query would not unsubscribe automatically to a query that failed to fetch.
  • Fixed an issue where, when using the cache with findId or findFirst, and requesting to load fields, if the cache contained a row without those fields, it would return the cached row without those fields.
  • Fixed an issue where in a filter that contained multiple instances of the same custom filter, with an 'and' condition did not work correctly
  • Graphql Mutations now display validation errors in the graphql way

[0.21.1] - 2023-06-25

  • Fixed issue with Field.Json fails to insert in case of array

[0.21.0] - 2023-06-22

  • Major improvements to the GraphQL support:
    • Better Query support
    • Mutation Support
    • Improved compatibility to standard GraphQL structures
    • Breaking Change Note that the GraphQL Schema has changed, and client code needs to be adjusted. If you run into any issues, please open a github issue or reach out to us on discord.
  • Improved SQL Log to Console see PR #204,

Big Thanks

  • to jycouet for his first two pull requests, and his help forming the GraphQL Schema according to best practices.
  • to talmosko for his help and improvements for the tutorials and documentation.

[0.20.6] - 2023-06-19

  • Fixed an issue when apiPrefilter was an arrow function, it did not affect get of a specific resource

[0.20.5] - 2023-06-11

  • fixed issue #200 transactions on mongo db

[0.20.4] - 2023-06-05

  • fixed issue with columns in postgres with casing in the db - sa createdAt
  • Issue #196 fixed - load options in live query
  • Fixed issue with apiReadAllowed:false when apiUpdateAllowed is set to undefined

[0.20.3] - 2023-05-23

  • Improved Open API Support

[0.20.2] - 2023-05-22

  • createdAt & updatedAt are by default allowApiUpdate false
  • Added apiPrefix to BackendMethod options to allow more control over backend method routes. #189

[0.20.1] - 2023-05-17

  • Improved support for compound id entity
  • Minor bug fixes
  • Improved memory usage

[0.20.0] - 2023-05-08

[0.19.0] - 2023-03-26

  • Repository
    • Added a validate method that returns an ErrorInfo object if invalid.
    • Added a fields member that can be used to access the metadata of specific fields, for example:
      repo.fields.title.caption
      //or
      repo.fields.title.inputType
    • The insert, validate, create, save and update value will now run fromJson and toJson for field values that do not match their type - for consistent behavior with the api
  • FieldMetadata
    • Added apiUpdateAllowed to query if update is allowed for this field
    • Added includedInApi to query of this field would be returned from the backend as part of the api
    • Added displayValue that can be used to achieve a consistent way a field is displayed.
    • Added toInput and fromInput methods that'll help with translating values from and to inputs.
  • getId method added to IdMetadata to enable extracting the id from immutable objects, this is mainly useful for entities where the id column is not called id :)
    repo.metadata.idMetadata.getId(task)

Breaking Changes

  • In EntityMetadata the apiUpdateAllowed, apiDeleteAllowed and apiInsertAllowed that previously were boolean fields, are now methods that accepts item and return true or false. This is useful for cases where the apiAllowed rules refer to the specific values of an entity.
    // Previously
    if (repo.metadata.apiDeleteAllowed) {
    }
    // Now
    if (repo.metadata.apiDeleteAllowed(task)) {
    }
  • The validate method in EntityRef and ControllerRef that previously returned true if valid, now returns undefined if valid and ErrorInfo if invalid
  • FieldMetadata's ValueConverter field's members are now mandatory and no longer optional - it's expected that they'll be implemented