Skip to main content

Changelog

All notable changes to OPRA are listed here, grouped by minor version.


1.29

1.29.0

@opra/core

  • ExecutionBundle — New base class that groups multiple ExecutionContext instances sharing a single transport connection or batch request. Provides contexts, transaction, success, finished, and error properties, and emits typed lifecycle events (before-execute, after-execute, error, finish). → Reference

  • Typed lifecycle eventsExecutionContext now accepts a generic event-map type parameter (ExecutionContext<T extends EventMap>). Transport-specific contexts (HttpContext, KafkaContext, RabbitmqContext, SocketioContext) all expose a typed Events interface. New per-context events: before-execute, after-execute, error, finish. New adapter-level events: context-before-execute, context-after-execute, context-finish, bundle-before-execute, bundle-after-execute, bundle-finish. → HttpContext Events · HttpAdapter Events

@opra/http

  • Batch requests (multipart/mixed) — The HTTP adapter now handles POST /$bundle with Content-Type: multipart/mixed. Each part of the request body is processed as an independent HTTP sub-request; responses are assembled into a single multipart/mixed reply. X-Request-Id headers are echoed back per part for client-side correlation. → Batch Requests

  • Transaction support — Append ?transaction=true to any /$bundle URL to wrap the entire batch in a single database transaction. The first operation that touches the database opens a session; all remaining operations in the bundle share it automatically. On full success the transaction commits; on any failure it rolls back. Supported out of the box by @opra/mongodb and @opra/sqb.

  • HttpBundle — New context object (extends ExecutionBundle) created for each batch request. Exposes request, response, contexts, size, transaction, and the full lifecycle event set. → Reference

@opra/client

  • HttpClientBase.bundle(requests) — Groups multiple HttpRequestObservable instances into a single POST /$bundle call. Returns an HttpBundleObservable whose getResponses() resolves with the sub-responses in input order. Requests bound to the bundle do not fire individual network calls; after resolution they can still be awaited via .getBody() / .getResponse() (served from a ReplaySubject cache). → HttpBundleObservable

  • HttpClientBase.transaction(requests) — Same as bundle(), appends ?transaction=true automatically.

  • HttpRequestObservable.requestId — Each request now carries a stable UUID used as the X-Request-Id part header when the request is serialized inside a bundle. Readable at any time regardless of whether the request is part of a bundle.

  • HttpBundleObservable — New class (extends Observable<HttpResponse[]>) returned by bundle() and transaction(). Serializes requests via serializeHttpRequest(), sends a single multipart/mixed POST, parses and distributes sub-responses by X-Request-Id. Supports param() for additional query parameters and can be used as an RxJS Observable.

Breaking changes

  • HttpBundle now extends ExecutionBundle — Previously HttpBundle extended ExecutionContext. Code that checks bundle instanceof ExecutionContext must be updated to bundle instanceof ExecutionBundle.

  • HttpRequest / HttpResponseHttpIncoming and HttpOutgoing have been renamed. Update any imports from @opra/http.

  • bundle property — The internal __bundle property on ExecutionContext has been renamed to bundle. Update any code that accessed context.__bundle directly.


1.28

1.28.4

  • allowNullOptionals option added to HTTP request body handling — when set, optional fields may be explicitly sent as null without triggering a validation error.

1.28.3

  • Fix: default value check for HTTP parameters was incorrectly evaluated in edge cases.

1.28.2

  • Fix: default values declared on query parameters were not applied when the parameter was absent from the request.
  • Fix: vg.required was used instead of vg.optional for parameters that have default values — parameters with defaults are now correctly treated as optional.

1.28.1

  • Default values can now be declared on @ApiField() and HTTP parameters (.QueryParam(), .PathParam(), .Header(), .Cookie()).
  • Default values are included in generated JSDoc comments for HTTP parameters.

1.28.0

  • Kafka adapter rewritten using @platformatic/kafka. The previous kafkajs-based implementation has been replaced; update any Kafka-specific configuration accordingly.
  • CI updated to Node.js 24.

1.27

1.27.0

  • SQB v5 migration — migrated to the new sql namespace introduced in SQB v5. Update @opra/sqb imports if you reference sql.* helpers directly.
  • SqbEntityService: the onError callback now receives the full command context, making it easier to log or transform errors with knowledge of which operation triggered them.

1.27.1–1.27.5

  • SQB peer dependencies updated to support both v5 and v6.
  • SKIP_KAFKA_TESTS and other SKIP_* environment variables added for selectively skipping integration tests in CI.
  • Dependency updates.

1.26

1.26.0

  • File handling in request bodiesBodyReader and MultipartReader now support saving incoming content directly to disk via a new LocalFile class. LocalFile auto-deletes the temp file when the instance is garbage-collected and provides file utility methods.

1.26.1

  • HttpContext.getBody() accepts a new toFile argument that saves the request body to a local file instead of buffering it in memory — useful for large uploads.

1.26.2–1.26.3

  • Fix: HttpContext.getBody() args parameter made optional.
  • Fix: SqbServiceBase.Options now correctly extends ServiceBase.Options.

1.26.4

  • oprimp CLI: added --type-imports flag — generated client code uses import type instead of import where possible.
  • Fix: DocumentNode creation now throws a clear error when OPRA metadata is missing from the target class.
  • Comment style standardised across all packages (migrated from JSDoc-style /** */ to standard block comments).

1.25

1.25.0

  • Dependency updates and TypeScript / Node.js compatibility improvements.

1.25.2

  • Fix: request bodies with Content-Type: application/yaml are no longer decoded as objects — they are passed through as raw strings.

1.25.3

  • New built-in simple types: creditcard, ean, ip, mobilephone, vatnumber.

1.25.4–1.25.5

  • mobilephone type: locale now defaults to "any" (validates any internationally formatted number).
  • mobilephone type: added strictMode option.
  • Removed built-in types passportnumber and varnumber.

1.25.6

  • HttpContext.getBody() now throws BadRequestError on decode failure instead of a generic error, so clients receive a proper 400 response with a structured error body.

1.24

1.24.0

  • YAML and TOML request body support — OPRA now parses application/yaml and application/toml request bodies natively.

1.24.1–1.24.2

  • SQB updated: support for query comments and index hints in generated SQL.

1.24.3

  • Fix: BodyReader would occasionally hang waiting for more data on certain Node.js stream implementations.

1.24.4

  • MultipartReader: uploaded files are now stored in the temp directory using their original filename rather than a random identifier.

1.23

1.23.0

  • Socket.IO controllers now always return a structured OperationResult envelope — errors and successes are consistently shaped for the client.

1.23.1

  • Fix: updating error.message after construction no longer caused error.stack to retain the original message.

1.23.2

  • Added createRootContext() method to PlatformAdapter for constructing a context outside of a normal request lifecycle (useful for startup tasks and background jobs).
  • Fix: operation results with array types were being double-wrapped in some configurations.

1.23.3

  • ErrorIssue.stack property type changed from object to string for consistency with standard error serialisation.

1.22

1.22.0

  • ESM only — CommonJS output has been dropped from all packages. Ensure your project uses "type": "module" or imports from an ESM-compatible bundler.
  • @WsParam(): added required option to mark a WebSocket operation argument as mandatory.

1.22.2

  • oprimp CLI now generates JSDoc documentation blocks for SimpleType attributes.
  • Fix: Socket.IO acknowledgement responses were being JSON-serialised twice in some adapters.

1.22.5

  • Fix: error responses now consistently use the errors array property. Previously some paths returned a singular error object.
  • Fix: WebSocket API operation arguments are now sorted by their declared parameter index.

1.22.6

  • Fix: datetime data type parsing failures on certain ISO string formats.
  • Fix: types with the same constructor name could cause a circular reference error in the registry.
  • Fix: array parameters using ArrayType were not being parsed correctly from query strings.

1.22.8–1.22.10

  • Fix: Socket.IO adapter crashed under certain concurrency conditions. Fixed across multiple patch releases.
  • Fix: Socket.IO adapter now returns a structured OperationResult for error responses (previously errors were not wrapped).

1.21

1.21.0

  • NestJS Socket.IO module (@opra/nestjs-socketio) — Socket.IO controllers can now be wired into a NestJS application using OpraSocketioModule, consistent with the existing HTTP module.

1.20

1.20.0

  • ArrayType — a new typed array wrapper that replaces the isArray flag on @ApiField(). Supports minOccurs / maxOccurs constraints and composes with any OPRA type.
  • Fix: Date and Buffer values returned from handlers were being decoded/encoded as plain strings.

1.19

1.19.0–1.19.2

  • Fix: date type now exports as string in oprimp-generated client code.
  • Fix: date and datetime parsing issues with certain ISO string formats.

1.19.5

  • WebSocket (Socket.IO) API support added to ApiDocument — WebSocket controllers appear in the API schema and can be introspected.
  • Message queue namespace renamed — all classes previously prefixed Rpc are now prefixed MQ (e.g., RpcControllerMQController). The new mq namespace is the canonical location.
  • ErrorIssue now accepts additional custom properties for richer error detail.

1.18

1.18.0

  • datetimetz data type — a timezone-aware datetime scalar that preserves the UTC offset during serialisation.
  • date and datetime types refactored; the datestring and datetimestring aliases have been removed — use date and datetime directly.
  • date, datetime, base64: new convertToNative option to decode strings into native JavaScript objects (Date, Buffer) at the codec layer.

1.17

1.17.0

  • RabbitMQ adapter migrated to rabbitmq-client library for improved connection handling and compatibility.

1.17.1

  • RabbitMQ adapter: Connection instance is now accessible via adapter.connection.

1.17.2

  • Fix: setting minValue: 0 on BigInt, Number, or Integer types was being silently ignored.

1.17.3

  • Removed isNotEmpty validation rule for required fields — presence is now the only check; emptiness is the application's responsibility.

1.17.4

  • Fix: codec generation no longer throws a maximum call stack error for complex types that contain a field referencing the same type (circular dependency).

1.16

1.16.0

  • RabbitMQ adapter now uses amqp-connection-manager for automatic reconnection and channel recovery.

1.15

1.15.0

  • UnionType data type added — a field can now accept a value that matches any one of a declared set of types.
  • MixinType argument style refactored for clarity.

1.14

1.14.0

  • Test framework migrated from Jest to Mocha.
  • TypeScript transpilation in tests migrated from ts-node to SWC for significantly faster test runs.
  • Code coverage migrated to c8.

1.13

1.13.0

  • Upgraded to Express v5.

1.12

1.12.0

  • Elasticsearch: ElasticEntityService.create() accepts a new replaceIfExists option.
  • Removed built-in i18n translations — error messages are now in English only.

1.12.2

  • Validation: required fields now apply an isNotEmpty check in addition to presence.

1.12.4

  • RabbitMQ: RabbitmqContext now exposes message, ack(), and nack() for manual acknowledgement control.

1.12.5

  • Fix: a message that fails payload validation is now acknowledged (not requeued) and the error is logged — previously the consumer could loop indefinitely on a poison message.

1.12.6

  • Entity services: added protected raw CRUD methods (_findRaw, _createRaw, etc.) for subclasses that need to bypass the standard codec pipeline.

1.11

1.11.0

  • NestJS packages split@opra/nestjs has been replaced by transport-specific packages: @opra/nestjs-http, @opra/nestjs-kafka, @opra/nestjs-rabbitmq. Update your imports and module registrations.

1.11.1

  • RabbitMQ: queue property added to RabbitmqContext.
  • OPRA packages moved from dependencies to peerDependencies in all adapter packages.

1.0–1.10

Initial stable releases establishing the core architecture: HTTP controller and operation decorators, the data type system (ComplexType, SimpleType, EnumType, MappedType), data service base classes for MongoDB, SQL (SQB), and Elasticsearch, the oprimp CLI code generator, NestJS HTTP integration, and the Kafka / RabbitMQ message queue adapters.