Skip to content

Changelog

What changed in each package, newest first. This page is made from the CHANGELOG.md files in the repo when the docs are built.

dox_annotation

3.0.0-alpha.5

  • New timestamps option on @DoxModel. timestamps: false turns off created_at and updated_at, like $timestamps = false in Laravel. createdAt: null or updatedAt: null turns off one of them.
  • New primaryKeyType option on @DoxModel. Use primaryKeyType: String for a UUID key. The default is int.
  • Fix: IHttpException.toResponse() now returns {"code": errorCode, "message": message} for a text message, so the client gets the errorCode. A Map message is returned as it is.

3.0.0-alpha.4

  • Version bump only, to match the other packages.

3.0.0-alpha.3

  • Version bump only, to match the other packages.

3.0.0-alpha.2

  • Needs Dart 3.13 or newer.
  • All dependencies updated to their latest versions.
  • OpenAPI annotations, all optional: @Summary, @Description, @Tags, @Request, @Body, @Query, @Response, @ApiDeprecated, @ApiIgnore, @DoxController. Lower case names work too (@summary(...)), except @Response.
  • The DTO annotations (@Dto, @Length, @Email, ...) live in dox_validation. dox_core exports them.
  • IDoxRequest has no validate() and no processInputMapper() any more. Use a DTO.
  • Breaking (small): these names are exported by dox_core too. If a file also imports a package with a Request or Response class (like package:http) without a prefix, add a prefix to that import.
  • New @DoxEnv() and @EnvKey('X') for the typed env class.

3.0.0-alpha.1

  • Version 3 of Dox. All Dox packages now share one version.
  • Needs Dart 3.6 or newer.
  • See the release notes for all main changes.

dox_auth

3.0.0-alpha.5

  • Breaking: JwtAuthDriver.expiresIn is 1 hour by default. Before, it was null, and tokens never expired.
  • New: named guards work. Use Auth(guard: 'admin') and AuthMiddleware(guard: 'admin'). Before, only defaultGuard was used.
  • A token keeps its guard name in the aud claim. A token from one guard does not work on another guard.
  • verifyToken checks the iss claim when issuer is set.
  • Breaking: AuthDriver methods get the guard name as a new parameter. AuthEngine().guard(name) replaces AuthEngine().driver and AuthEngine().provider.

3.0.0-alpha.4

  • Version bump only, to match the other packages.

3.0.0-alpha.3

  • Version bump only, to match the other packages.

3.0.0-alpha.2

  • Needs Dart 3.13 or newer.
  • All dependencies updated to their latest versions.
  • dart_jsonwebtoken 3.4 (pointycastle 4).

3.0.0-alpha.1

  • Version 3 of Dox. All Dox packages now share one version.
  • Needs Dart 3.6 or newer.
  • See the release notes for all main changes.
  • Uses dox_orm (was dox_query_builder).
  • dart_jsonwebtoken 3.

dox_builder

3.0.0-alpha.5

  • @DoxModel(timestamps: false) makes a model without createdAt and updatedAt. createdAt: null or updatedAt: null turns off only one.
  • The primary key field has the type of @DoxModel(primaryKeyType: ...). It was always int?. The default is still int. The OpenAPI model schema uses the same type.
  • Fix: a preloaded relation with a two word name (like userInfo) was missing from toJson(). The generator looked for user_info in the preload list, but the list has userInfo.
  • Fix: the OpenAPI route scanner now puts one / between a group and a route path, like the router does.

3.0.0-alpha.4

  • Version bump only, to match the other packages.

3.0.0-alpha.3

  • Version bump only, to match the other packages.

3.0.0-alpha.2

  • Needs Dart 3.13 or newer.
  • All dependencies updated to their latest versions.
  • New builder dox_builder:openapi. It writes lib/openapi.g.dart with the OpenAPI docs of the app: it reads the Route.* calls, the controllers, the @Dto classes and the models. It writes nothing when the package has no controllers.
  • DtoJsonSchema, ModelSchema and JsonSchemaReader: the JSON Schema of a @Dto class, a model or any Dart type. Other builders can use them.
  • New: the DTO generator. For each @Dto class it writes $<Name>Dto (a const DtoSchema<Name>) into the .g.dart part: plain if checks per field, the converter, fromMap, toMap and the JSON Schema. It stops the build with a clear error for a bad DTO (a field that is not final, a type that is not supported, a rule that does not fit, a bad regex, ...).
  • New builder dox_builder:dtos. It writes lib/dtos.g.dart with every DTO of the app, for AppConfig(dtos: dtos). Two DTOs with the same name stop the build.
  • DtoReader: the one place that knows DTO keys. The OpenAPI docs use the same keys as the DTO (snake_case by default, @Name, @Dto(keyCase:)).
  • OpenAPI: @Regex (was @Pattern). @Format is removed. Form requests are removed.
  • Fix: the OpenAPI route list has the full path, with the Router prefix and Route.group() prefixes. Two '/' routes in two groups now each get their docs.
  • OpenAPI path params: every positional argument that is not the request and not a DTO.
  • New: @DoxEnv() classes get _$<Class> in the .g.dart part. Each getter is read from the env once, converted to its type (String, int, double, num, bool, Uri, Duration, enum, List) and kept in a final field. A getter body is the default. A nullable getter is optional. load() throws one EnvException with every missing or bad key.

3.0.0-alpha.1

  • Version 3 of Dox. All Dox packages now share one version.
  • Needs Dart 3.6 or newer.
  • See the release notes for all main changes.
  • Works with analyzer 5 and 6.

dox_cache

3.0.0-alpha.5

  • Version bump only, to match the other packages.

3.0.0-alpha.4

  • Version bump only, to match the other packages.

3.0.0-alpha.3

  • New: getRaw(key) gives the stored value as JSON text, with no decode. Use it to send a cached value as a JSON response. Memory and Redis return the stored text as is. A stored String comes back with its quotes ("bar"). The stored format did not change, so old values still read the same.
  • Faster get: a plain store builds the key with no async step. itemKey now returns FutureOr<String>. Memory get costs about 0.6 µs instead of 0.86 µs. Memory getRaw costs about 0.3 µs.
  • New Redis option pool_size: the most connections one store opens (ioredis maxConnection). Default is 10, the same as before.
  • Uses ioredis 2.0.0-alpha.2. It sends all commands on one shared connection and writes them together (auto-pipelining). A Redis read costs much less CPU. The cache now uses one connection per store, so pool_size rarely matters.

3.0.0-alpha.2

  • Needs Dart 3.13 or newer.
  • All dependencies updated to their latest versions.

3.0.0-alpha.1

  • Uses ioredis 2. Redis error replies throw RedisError.
  • Redis: no value size limit by default (was 60 KB). maxValueBytes is still there if you want one.
  • Redis: many uses one MGET, putMany uses one pipeline, flush uses SCAN + DEL (no Lua).
  • First release.
  • CacheManager with named stores and custom drivers.
  • Drivers: memory (with LRU), file, Redis, null.
  • remember, pull, add, increment, many, tags and atomic locks.

dox

Unreleased

  • Fix: dox key:generate dropped .env lines with more than one = (like DATABASE_URL=postgres://u:p@h/db?sslmode=require). It also dropped comment lines. Now it only changes the APP_KEY line. Every other line stays as it is.
  • Fix: dox create crashed with Failed to decode data using encoding 'utf-8' when the template had a binary file (for example db/dox.sqlite-shm). It now skips files that are not UTF-8 text. It only writes a file when its content changes.

3.0.0-alpha.5

  • Fix: dox create my_app without --version crashed with a RangeError.
  • Fix: dox create picked the GitHub "latest" template release, which skips pre-releases. During the 3.x alpha that gave the old 2.x template. It now takes the newest template with the same major version as the CLI.
  • Fix: dox env:generate read KEY=3000 # note as text, not as an int. A # after a space is now a comment.
  • Fix: dox update ran a plain dart pub global activate dox, which skips pre-releases. During the 3.x alpha it installed the old 2.x CLI. It now installs the newest version with the same major version as the CLI, from the pub.dev version list.

3.0.0-alpha.4

  • Version bump only, to match the other packages.

3.0.0-alpha.3

  • Version bump only, to match the other packages.

3.0.0-alpha.2

  • Fix: dox build no longer passes --delete-conflicting-outputs to build_runner (it was removed and printed a warning).
  • Needs Dart 3.13 or newer.
  • All dependencies updated to their latest versions.
  • dox build now runs dart build cli (AOT, with build hooks). The output is build/bundle/. Start it with cd build/bundle && ./bin/server.
  • New dox create:dto <name>: makes lib/app/http/dtos/<name>.dto.dart. dox create:request is removed.
  • dox create:controller -r uses int id for the resource methods.
  • New dox openapi:generate [dir]. It runs the app's bin/openapi.dart and writes openapi.json and openapi.yaml (default storage/openapi).
  • New dox env:generate: makes lib/config/env.dart (the typed env class) from .env.example.
  • New dox env:check: loads the typed env and prints every missing or bad key (exit code 1).

3.0.0-alpha.1

  • Version 3 of Dox. All Dox packages now share one version.
  • Needs Dart 3.6 or newer.
  • See the release notes for all main changes.
  • Generated models import package:dox_orm/dox_orm.dart.

dox_core

3.0.0-alpha.5

  • Fix: CORS origin can be a list. Dox compares the request Origin with the list and sends back only the origin that matches, or no header. Before, it joined the list with commas, and browsers rejected it. A list also sends Vary: Origin.
  • Breaking: AESEncryptor now uses AES-GCM with a random nonce for each message. Before, it used AES-CTR with an all-zero nonce and no message check. Old encrypted cookies and values can not be read.
  • Breaking: AESEncryptor.decode throws DecryptException (400) when the text was changed or the key is wrong. Before, it printed an error and returned ''.
  • req.cookie() returns null for an encrypted cookie that can not be decrypted.
  • Fix: Hash.verify returns false for a malformed hash. Before, it threw.
  • AESEncryptor and DecryptException are now exported from package:dox_core/dox_core.dart.
  • Fix: in .env, KEY=value # note gave the value value # note. A # after a space now starts a comment. A # inside quotes, or with no space before it, is kept.
  • Fix: the .env parser removed every quote character inside a value. Now only the quotes around the value are removed.
  • Fix: HEAD requests got 404, also HEAD /docs. A HEAD request now runs the GET route of the same path. The answer has the status and headers of GET, with no body.
  • New: Dox listens on PORT when APP_PORT is not set. Cloud Run, Fly, Render and Heroku set PORT. APP_PORT still wins.
  • New: AppConfig.host and the env var APP_HOST pick the network interface to listen on, like 127.0.0.1. The default is the same as before: all interfaces (::, IPv6 and IPv4).
  • Fix: the start log always said http://127.0.0.1:<port>. It now shows the real host and port, like http://[::]:3000.
  • Removed the unused sprintf dependency.
  • New: graceful shutdown. On SIGTERM or SIGINT every isolate stops taking new connections and lets open requests finish, up to AppConfig.shutdownTimeout (default 8 seconds). Then Dox runs DoxShutdown services and exits with code 0. Before, open requests were cut. A second signal stops at once.
  • New: DoxShutdown. A service that also implements it gets shutdown() in every isolate on stop, to close connections.
  • New: await Dox().stop() stops the server gracefully in every isolate, without exit.
  • Fix: an s3 storage disk without bucket, key or secret failed with Null is not a subtype of String. Now it fails with a clear message that names the missing setting.
  • Fix: a URL with no route now answers like a thrown NotFoundHttpException. The body is JSON ({"code": "not_found", "message": "GET /x not found"}), and the app responseHandler runs for it, so apps can format it.
  • Fix: the error answer of an IHttpException now has its errorCode. A text message gives {"code": "<errorCode>", "message": "<text>"} as JSON. Before, the body was plain text and errorCode was never sent. A Map message (like validation errors) is still sent as it is.
  • Fix: the Logger now reads LoggerConfig.level. Lines below that level are not printed. Levels from low to high: debug, info (and success), warn, error (and danger).
  • Fix: Route.group('blogs') with Route.get('all') made /blogsall. Path parts now join with one /. This also works for nested groups, Route.prefix and Route.resource.
  • Fix: Route.resource hid every error from the controller. Now it only skips methods the controller does not have.

3.0.0-alpha.4

  • Version bump only, to match the other packages.

3.0.0-alpha.3

  • New: Cache().getRaw(key) gives the cached value as JSON text, with no decode. Send it as a JSON response with no extra encode step.
  • New Redis cache option pool_size (see dox_cache).

3.0.0-alpha.2

  • New default server: dox_http_native (Rust hyper parses HTTP, your code stays in Dart). Hello world goes from about 41k to about 144k req/s on one isolate. Set server: ServerBackend.dartIo in AppConfig (or DOX_SERVER=dartio) to use dart:io. Dox uses dart:io by itself, with one warning line, when the native library does not load, and for apps with WebSocket or Socket.IO routes.
  • Faster requests: a simple GET hello world went from about 31k to about 40k req/s on one isolate (plain dart:io is about 46k). A request with no body and sync middleware and controller now runs with no Future. req.ip(), the query, req.all() and cookies are read on first use only. Reading the client ip was the biggest cost, because it asks the socket. Clean paths skip the two regex calls, and plain routes are found with a map lookup.
  • Fix: a @Dto body with a RequestFile field shows as multipart/form-data in the OpenAPI docs.
  • Fix: req.ip() gave ::ffff:127.0.0.1 for IPv4 clients. Now it gives 127.0.0.1. The same goes for X-Forwarded-For hops.
  • Needs Dart 3.13 or newer.
  • All dependencies updated to their latest versions.
  • Removed the encrypt package (not maintained, and it blocked pointycastle 4). AES for cookies and the file cache now uses pointycastle 4. The output is the same, so old cookies and cache files still decode.
  • Fix: Env.get() of a missing key with no default gave the text "null". A missing APP_KEY became the key "null", which anyone can guess. Now String gives '', String? gives null, and int/num/double/bool throw a clear error. New: Env.get<bool>().
  • Startup stops with an error when APP_KEY is empty and APP_ENV=production. Other environments log a warning.
  • New: typed input with DTOs. A controller asks for a @Dto class by type: store(CreateUser body). Dox reads the body (or the query for GET), checks it, and answers 422 with {"items.1.quantity": "..."} when it is wrong. await req.validate<T>() does the same inside a method. See the Validation guide.
  • New: AppConfig(dtos: dtos) (from lib/dtos.g.dart) and AppConfig(validationMessages:) for other languages. req.locale is the first Accept-Language.
  • New: typed controller parameters. DoxRequest anywhere, one @Dto, and String, int, double, num, bool path params by position. A path param that does not fit its type answers 404. The types are read once at start; an unknown type stops the server with a clear error.
  • New: optional path params {id?}.
  • New: query strings and form data with repeated keys (tags=a&tags=b) and bracket keys (address[city], items[0][name]) for DTOs.
  • A DTO answers 400 for a body that is not valid JSON, and 415 for a body type it can not read.
  • RequestFile implements FileInput and keeps its first bytes, so @Mimes and @Image check the real file type.
  • Breaking: removed req.validate(Map), req.validateAsync(), FormRequest, AppConfig(formRequests:), DoxValidator, IocContainer.registerRequest() and processInputMapper(). Use a DTO. req.validateSchema(schema) stays for input you only know at runtime.
  • Breaking: a controller with more path params than the route has {...} params stops the start. Before, the extra ones got ''.
  • Fix: a typed path param like int id gave a 500 (it was always a String).
  • A ValidationException from dox_validation (for example schema.parse() in a controller) answers 422.
  • dox_core exports dox_validation (not its ValidationException), with the DTO annotations. dox_orm also has Schema, and package:uuid has Uuid: use hide or a prefix in a file that needs both.
  • Breaking: Cache() runs on dox_cache. AppConfig.cache is a dox_cache CacheConfig(defaultStore:, stores:) with option maps. CacheDriverInterface and FileCacheDriver are removed. Values must be JSON types. put without a duration keeps the value forever (was 1 hour). New: add, pull, increment, decrement, remember, rememberForever, lock, tags.
  • Breaking: Storage() runs on dox_storage. AppConfig.fileStorage is now AppConfig.storage (StorageConfig(defaultDisk:, disks:) with option maps for local, s3, memory). StorageDriverInterface and LocalStorageDriver are removed. An unknown disk name throws.
  • Storage().stream() and download() stream from any disk (S3 too), with Content-Length. New: url, signedUrl, use() for the full Disk.
  • New Route.files('files') serves local signed URLs (403 for a bad signature). New catch-all route param {path*}.
  • OpenAPI: AppConfig(openApi: OpenApiConfig(...)) adds /docs, /openapi.json and /openapi.yaml. On by default only when APP_ENV is development or local. Bodies come from the route body: option or a DTO. Dox().writeOpenApi(dir) writes the files.
  • RouteData.preMiddleware now holds the group and router middleware.
  • Socket.IO: AppConfig(socketIo: SocketIoConfig(enabled: true, ...)) serves /socket.io/ on the app port, before the router. Route.mount(prefix, handler) is the raw hook. Off by default.
  • No extra work per request when OpenAPI or Socket.IO is off.
  • OpenAPI docs are automatic. dart run build_runner build writes lib/openapi.g.dart. Pass it as OpenApiConfig(registry: openApiRegistry). Each route then gets its summary and description (from the /// comment), tags, Class.method operation id, typed path params, request (a @Dto class) and answer schema (from the return type), plus 401, 404, 422 and 500.
  • A middleware whose class name ends with AuthMiddleware adds bearerAuth to the docs, with no config.
  • A GET or DELETE request class becomes query params in the docs.
  • dox_core exports OpenApi, OpenApiRegistry, OpenApiOperation, OpenApiRouteBinding and ResponseDoc of dox_openapi.
  • The OpenAPI JSON and YAML are encoded once and kept, not on each request.
  • New EnvReader and EnvException for the typed env class (@DoxEnv()). The real environment wins over .env, the same as Env.get(). Env.get() stays for dynamic keys.
  • OpenAPI: /docs uses Scalar by default. OpenApiConfig(ui: DocsUi.swagger) gives Swagger UI. New OpenApiConfig options: scalar: ScalarOptions(...) (theme, dark mode, download button, proxy) and pageTitle.

3.0.0-alpha.1

  • Version 3 of Dox. All Dox packages now share one version.
  • Needs Dart 3.6 or newer.
  • See the release notes for all main changes.
  • Faster: streamed bodies, all CPU cores, faster router.
  • uuid 4 and mime 2.

dox_http_native

3.0.0-alpha.5

  • New: NativeHttpServer.bind(port, address: ...) listens on one host, like HttpServer.bind. An InternetAddress or a host name. With no address it listens on all interfaces, as before. server.address is the real address.
  • Fix: close() never finished when nobody called listen() on the server.
  • Native ABI 3 (dox_start takes the host). Needs a new native library build. Until the next release, the build hook builds it with cargo.
  • New: close() is graceful, like dart:io. The server stops taking connections at once, each open connection closes after its current answer, and the future completes when all are closed. close(force: true) closes every connection at once.

3.0.0-alpha.4

  • Version bump only, to match the other packages.

3.0.0-alpha.3

  • DOX_HTTP_THREAD=shared runs one dox-http thread for all isolates. Default is still one thread per isolate, which measured faster.
  • Less work per request: request headers are read one name at a time, answers are not copied again in Rust, one wake per answer batch.
  • Native ABI 2 (new header layout in the request record). Needs a new native library build.

3.0.0-alpha.2

  • First release.
  • Native HTTP/1.1 server: Rust (hyper, tokio) owns the sockets and parses HTTP. Handlers stay in Dart.
  • Implements the dart:io HttpServer, HttpRequest and HttpResponse API, so code written for dart:io works unchanged.
  • One server per isolate on the same port (SO_REUSEPORT on Linux and macOS).
  • 400 for bad requests, 431 for big headers, 413 for big bodies.
  • The build hook downloads a ready-built library. No Rust needed.

dox_migration

3.0.0-alpha.5

  • DATABASE_URL support. When it is set, it wins over DB_CONNECTION and the other DB_* keys. Its sslmode (Postgres) or ssl (MySQL) option turns TLS on.
  • A DB_HOST that starts with / is a Postgres Unix socket folder, like /cloudsql/project:region:instance on Cloud Run.
  • Migrations read real environment variables too. Before, a .env file hid them. Now a real env var wins over .env, the same as Env.get() of dox_core. An empty value, or null, counts as missing.

3.0.0-alpha.4

  • Version bump only, to match the other packages.

3.0.0-alpha.3

  • Version bump only, to match the other packages.

3.0.0-alpha.2

  • Needs Dart 3.13 or newer.
  • All dependencies updated to their latest versions.
  • sqlite3 3 (SQLite is bundled, no system library needed).

3.0.0-alpha.1

  • Removed the dox_migration executable from pubspec (its script was removed before). Use the dox CLI.
  • Added SQLite: DB_CONNECTION=sqlite and DB_DATABASE=<file path>.
  • MySQL driver is now mysql_dart (was mysql1). The MySQL 8 default login (caching_sha2_password) works.
  • migrate() and the other commands also take a pool (postgres Pool, mysql MySQLConnectionPool). Each file runs in one transaction on one connection.
  • Breaking: a passed mysql connection must be a mysql_dart MySQLConnection or MySQLConnectionPool (not mysql1).
  • Needs Dart 3.6 or newer.

3.0.0

  • Support MySQL. Set DB_CONNECTION=mysql in .env (default is postgres)
  • Run each statement of a .sql migration one by one, inside a transaction
  • Rollback undoes only the last batch, newest first. Add step, reset() and refresh()
  • Stop at the first failed migration
  • Fix .sql parsing: a - in the sql no longer cuts the up or down part
  • Fix statement split: ; inside quotes, comments or $$ bodies does not split

dox_mysql_native

3.0.0-alpha.5

  • The hook comment says how to fill the sha256 list from a release: dart run bin/native_hashes.dart <tag>. The list stays empty until the first release.

3.0.0-alpha.4

  • Version bump only, to match the other packages.

3.0.0-alpha.3

  • Breaking: this package no longer depends on dox_orm. MysqlNativeDriver moved into dox_orm, which now uses it as its default MySQL driver. This package keeps MysqlNativePool, with the same API.

3.0.0-alpha.2

  • First release.
  • Native MySQL and MariaDB driver: Rust (mysql_async, tokio) runs the pool and a prepared statement cache per connection. Dart gets typed rows.
  • MysqlNativeDriver plugs into the Dox ORM. The ORM gets the same types as with the Dart driver (mysql_dart).
  • Works with MySQL 8.4 (caching_sha2_password) and MariaDB 11.
  • The build hook downloads a ready-built library. No Rust needed.

dox_openapi

3.0.0-alpha.5

  • Version bump only, to match the other packages.

3.0.0-alpha.4

  • Version bump only, to match the other packages.

3.0.0-alpha.3

  • Version bump only, to match the other packages.

3.0.0-alpha.2

  • A request body with a file field (format: binary, also in a list) uses multipart/form-data instead of application/json, so the /docs page can send files. RouteDoc(bodyMediaType:) sets it by hand.
  • Needs Dart 3.13 or newer.
  • All dependencies updated to their latest versions.
  • DoxRouteAdapter reads preMiddleware and body from a route when it has them.
  • A Dox catch-all param {path*} and an optional param {id?} become {path} and {id} in the document.
  • OpenApiOperation.formRequest is removed (form requests are gone).
  • New OpenApiRegistry, OpenApiOperation and OpenApiRouteBinding: the docs that dox_builder finds in the code. OpenApiRegistry.find() matches them to a live route.
  • RouteDoc and ApiDoc.route() take deprecated.
  • OpenApiServer builds and encodes the document once, on the first call, and keeps it. Make a new OpenApiServer after you change the OpenApi.
  • OpenApi.yamlEmitter is now a public field.
  • /docs uses Scalar (@scalar/api-reference 1.75.1) by default. OpenApiServer(ui: DocsUi.swagger) gives Swagger UI. ScalarOptions sets the theme, dark mode, download button and proxy (off by default). The title and the config are escaped.
  • Swagger UI updated to 5.34.0.

3.0.0-alpha.1

  • First release.
  • Build an OpenAPI 3.1 document with OpenApi and ApiDoc.
  • Add undocumented Dox routes with DoxRouteAdapter.
  • Output as JSON and YAML, write files, serve /openapi.json, /openapi.yaml and /docs.

dox_orm

3.0.0-alpha.5

  • DATABASE_URL support. ConnectionConfig.fromUrl() reads postgres://, postgresql://, mysql://, mariadb://, sqlite: and file: urls: url-decoded user and password, host, port, database, sslmode and other options (they go to extra).
  • DatabaseConfig has a new url. It is DATABASE_URL from the environment when not given. When it is set, it wins: it replaces the default connection. Pass url: '' to turn it off.
  • Postgres Unix sockets. A host that starts with / is a socket folder, like /cloudsql/project:region:instance on Cloud Run. Works on the native and the Dart driver. Use ?host=/cloudsql/... in a url.
  • Breaking: the finders are typed. On a model, get() and all() give Future<List<T>>, find() and getFirst() give Future<T?>, and paginate() gives Future<Pagination<T>> (page.data is a List<T>). QueryBuilder.table() gives maps: get() is Future<List<Map<String, dynamic>>> and getFirst() is Future<Map<String, dynamic>?>. QueryBuilder.table() has no type argument and no second argument any more.
  • Breaking: groupBy() and rawQuery() rows are maps, so use them on QueryBuilder.table(). On a model, get() throws a StateError for them. count() with groupBy() still works on a model.
  • Breaking: the default foreign keys use the model name, like Laravel. A User model with table: 'users' gives user_id, not users_id. The default pivot table of @ManyToMany also uses the model names (artist_song). Keys you set yourself work as before. New Model.foreignKeyName gives the default key of a model.
  • Breaking: save() inserts when the model is new and updates when the row is in the table (model.exists). Before, it updated when the primary key was set. So a new model with a key you set yourself, like a UUID, is now inserted.
  • QueryBuilder.query() has a new connection parameter, to run a raw query on a named connection.
  • Fix: withConnection() did not reach save(), delete(), forceDelete() and restore(). They used the default connection. Now they use the connection of the model. Models that a query returns keep the connection of the query, and relation queries use the connection of the parent model. Model.withConnection() returns the model, so Blog()..withConnection('other') works.

3.0.0-alpha.4

  • Version bump only, to match the other packages.

3.0.0-alpha.3

  • Postgres and MySQL/MariaDB now use the native drivers by default (dox_postgres_native and dox_mysql_native). You do not change any config. If the native library does not load, the ORM uses the Dart driver and prints one warning line. Set DOX_DB_DRIVER=dart, or extra: {'native': false} on one connection, to use the Dart driver. driverFactory still wins over all of this.
  • Breaking: PostgresNativeDriver and MysqlNativeDriver moved into dox_orm. Import them from package:dox_orm/dox_orm.dart.
  • PostgresNativeDriver.query does one less async step per query.
  • Faster queries on all databases. Each connection keeps its prepared statements (LRU, 100 by default, extra['preparedStatementCacheSize']). The same query now has the same sql text, so the statements are reused. find() no longer sends LIMIT 1 OFFSET 0: LIMIT and OFFSET are only sent when set, and never OFFSET 0. Less work per row when models are built. A find by id on SQLite went from 23 µs to 6 µs.
  • Less Dart work per query. A plain find() builds its SQL once per driver, table and column, and reuses it. A model makes its maps and lists only when they are used. Rows become models without one more await when there is nothing to preload. ORM work per World().find(id) went from 2.6 µs to 1.0 µs (no database, AOT).
  • New ConnectionConfig.driverFactory: plug in your own driver class with one line. The default and the named connections use it.

3.0.0-alpha.2

  • Needs Dart 3.13 or newer.
  • All dependencies updated to their latest versions.
  • sqlite3 3. SQLite is now bundled by a build hook, so no system libsqlite3 is needed.
  • Breaking: dart compile exe does not work with build hooks. Use dart build cli (or dox build).
  • SQLite: set busy_timeout before journal_mode = WAL. Before, many isolates that opened the same file at start could fail with "database is locked".
  • New DTO rules @Unique('users', column: 'email', ignoreParam: 'id') and @Exists('teams'). They run after all other checks. A List field is checked with one WHERE IN query. Soft-deleted rows count too.

3.0.0-alpha.1

  • Renamed from dox_query_builder to dox_orm. Change package:dox_query_builder/dox_query_builder.dart to package:dox_orm/dox_orm.dart. The old package still works for now: it only re-exports this one.
  • Added SQLite (Driver.sqlite, package sqlite3). database is a file path or :memory:. Uses WAL, busy_timeout and foreign keys. One connection per isolate. See the docs for limits.
  • MySQL driver is now mysql_dart (was mysql1). The MySQL 8 default login (caching_sha2_password) works. It uses a real connection pool (maxConnectionCount, default 10), prepared statements with bound values, and one pooled connection per transaction.
  • Breaking: extra['characterSet'] (a mysql1 type) is no longer read. Use extra['collation'] (default utf8mb4_general_ci). getDatabaseConnection() for MySQL now returns a MySQLConnectionPool.
  • Breaking: MySQL TIME columns are now a String (was a Duration). BLOB columns are Uint8List (was text).
  • ConnectionConfig: user, password and port are optional (not used by SQLite).
  • Needs Dart 3.6 or newer.
  • Added whereNull, whereNotNull, orWhereNull, orWhereNotNull, whereNotIn, orWhereIn, orWhereNotIn and selectRaw.
  • Added QueryBuilder.transaction(). Postgres now uses a real connection pool (maxConnectionCount) and no longer runs each query in its own transaction.
  • Added boolean() schema column (Postgres BOOLEAN, MySQL TINYINT(1), read as bool).
  • Table and column names are now quoted ("name" on Postgres, `name` on MySQL). On Postgres, quoted names are case sensitive. Use selectRaw/whereRaw for raw SQL.
  • count() ignores limit, offset and orderBy. With groupBy it now returns the number of groups (before: the size of the first group).
  • save() can set a field to null on update.
  • insert() works with any primary key type (uuid strings too).
  • model.delete() and model.forceDelete() only delete that record. Before, they had no where condition.
  • forceDelete() also deletes soft deleted rows. withTrash(false) on a model without soft deletes no longer adds a deleted_at filter.
  • hasOne, hasMany and manyToMany work with a custom localKey.
  • insertMultiple() uses keys from all rows. Missing keys use the column default.
  • MySQL: only JSON columns are decoded (arrays too). MariaDB keeps decoding JSON-like text, because it stores JSON as text.
  • Schema: unique() on a column that is already unique is skipped. Default values are escaped.

dox_postgres_native

3.0.0-alpha.5

  • The hook comment says how to fill the sha256 list from a release: dart run bin/native_hashes.dart <tag>. The list stays empty until the first release.
  • A host that starts with / is a Unix socket folder (eg. Cloud SQL /cloudsql/project:region:instance). A test checks it.

3.0.0-alpha.4

  • Less work per request. Rust copies a batch of requests once and keeps slices of it, instead of one copy of the SQL and of each parameter. A batch of plain queries uses one timeout timer, not one per query. Dart keeps waiting requests in a list, not a map.

3.0.0-alpha.3

  • Column names and types are decoded once per result shape. The next result with the same columns reuses them.
  • Breaking: this package no longer depends on dox_orm. PostgresNativeDriver moved into dox_orm, which now uses it as its default Postgres driver. This package keeps PgNativePool.
  • Fix: a request never got an answer in two cases. A value that Dart can not decode (eg. a timestamp out of the DateTime range) lost every other result of the same batch. A request sent to a transaction after its end (eg. a second rollback) was dropped. Both now fail with a clear error.
  • A request that gets no answer in 5 minutes fails with a timeout error (like queryTimeout of the postgres package). Connect timeout is 15 s. A transaction that Dart does not end in 5 minutes is rolled back, so its connection goes back to the pool.
  • tool/stress.dart: a stress test that finds requests that never finish.
  • Faster queries. Plain queries now share connections: tokio-postgres sends the queries of one connection together (pipelining). One tokio task runs each batch from Dart, not one task per query. The SQL bytes are cached, and binding named parameters builds no extra Set.

3.0.0-alpha.2

  • First release.
  • Native Postgres driver: Rust (tokio-postgres, deadpool-postgres) owns the connections. Your code stays in Dart.
  • PostgresNativeDriver for the Dox ORM. Same types and exceptions as the postgres package.
  • PgNativePool: queries, transactions, one pool for many isolates.

dox_query_builder

3.0.0-alpha.5

  • Version bump only, to match the other packages.

3.0.0-alpha.4

  • Version bump only, to match the other packages.

3.0.0-alpha.3

  • Version bump only, to match the other packages.

3.0.0-alpha.2

  • Needs Dart 3.13 or newer.
  • All dependencies updated to their latest versions.

3.0.0-alpha.1

  • This package is renamed to dox_orm. It now only re-exports package:dox_orm/dox_orm.dart.
  • Please depend on dox_orm and change your imports. See the README.

dox_socketio

3.0.0-alpha.5

  • Version bump only, to match the other packages.

3.0.0-alpha.4

  • Version bump only, to match the other packages.

3.0.0-alpha.3

  • Version bump only, to match the other packages.

3.0.0-alpha.2

  • Needs Dart 3.13 or newer.
  • All dependencies updated to their latest versions.

3.0.0-alpha.1

  • Uses ioredis 2.
  • RedisAdapter listens with PSUBSCRIBE, so it also gets the room channels that the Node.js redis adapter uses for one room. onRedisMessage now takes (pattern, channel, message).
  • First version. Socket.IO v4 server (Engine.IO v4, Socket.IO protocol v5).
  • Polling and websocket transports, upgrade, heartbeat, CORS.
  • Namespaces, middleware, rooms, broadcast, acks, binary.
  • In-memory adapter and Redis adapter.

dox_storage

3.0.0-alpha.5

  • Version bump only, to match the other packages.

3.0.0-alpha.4

  • Version bump only, to match the other packages.

3.0.0-alpha.3

  • Version bump only, to match the other packages.

3.0.0-alpha.2

  • Needs Dart 3.13 or newer.
  • All dependencies updated to their latest versions.

3.0.0-alpha.1

  • Initial version.
  • DriveManager and Disk with a FlyDrive-like API.
  • Drivers: LocalDriver, S3Driver (AWS S3, R2, MinIO, Spaces, GCS interop), MemoryDriver.
  • AWS Signature V4 signing, presigned download and upload URLs, multipart upload.
  • DriveManager.fake() for tests.

dox_validation

3.0.0-alpha.5

  • Version bump only, to match the other packages.

3.0.0-alpha.4

  • Version bump only, to match the other packages.

3.0.0-alpha.3

  • Version bump only, to match the other packages.

3.0.0-alpha.2

  • A JSON body that is not an object now says The request body must be a JSON object. (key _root). Change it with the message key _root.object.
  • Needs Dart 3.13 or newer.
  • All dependencies updated to their latest versions.
  • New: DTOs. A class with @Dto() and rule annotations (@Length, @Email, @Min, @Regex, @MaxSize, ...). dox_builder writes a const DtoSchema<T> with the checks, a converter and the JSON Schema. See the Validation guide.
  • New: DtoSchema<T> with validateMap, safeValidateMap, fromMap, toMap and toJsonSchema. It is also a Schema<T>.
  • New: Maybe<T> knows a missing key from null. DtoErrors for checks across fields in validate().
  • New: FileTypes finds the real type of a file from its first bytes. @Image() and v.file().image() do not allow svg.
  • New: MessageRequest.locale, ParseState.params. A message set on a rule is used as it is; the resolver only fills its placeholders.
  • Rule has a const constructor and a final message, so a rule class works as an annotation. AsyncRule.failedItems() checks a list in one call.
  • FileInput has length and head (the first bytes).
  • Schema has a const constructor. The fluent schemas extend BaseSchema.
  • Text length messages say "characters".
  • Breaking: removed v.fromRules(), v.registerRule(), RuleRegistry, RuleDefinition, CallbackRule and all rule strings. Use a DTO, or a Rule<T> class.

3.0.0-alpha.1

  • First release of dox_validation.
  • Fluent schema builder: string, int, num, bool, date, enum, literal, list, object, map, union, any, file.
  • optional, nullable, nullish, defaultTo, transform, refine, superRefine, async refinements.
  • Coercion with v.coerce for query strings and form data.
  • parse, safeParse, parseAsync, safeParseAsync with issue paths.
  • Standard Schema interface (StandardSchema).
  • JSON Schema (draft 2020-12 / OpenAPI 3.1) export with toJsonSchema().
  • Custom Rule classes and a global MessageResolver.
  • Laravel style string rules with v.fromRules().

dox_websocket

3.0.0-alpha.5

  • Version bump only, to match the other packages.

3.0.0-alpha.4

  • Version bump only, to match the other packages.

3.0.0-alpha.3

  • Version bump only, to match the other packages.

3.0.0-alpha.2

  • Needs Dart 3.13 or newer.
  • All dependencies updated to their latest versions.
  • WebsocketAdapterInterface.emit now has a void return type.

3.0.0-alpha.1

  • Version 3 of Dox. All Dox packages now share one version.
  • Needs Dart 3.6 or newer.
  • See the release notes for all main changes.
  • uuid 4 and ioredis 2.