April 2026 (version 2.26.04.23)

reviewed: 23 April 2026

📦 Summary

This release delivers performance enhancements to the core framework, including optimized tokenization and Property Bag string handling that drastically reduce memory usage and parsing times for large scripts.

We've introduced powerful new developer tools, a full featured CMS CLI (cms.exe) for scripting and interactive testing, a massively expanded DOCX OpenXML Handler for programmatic document generation, and a new Mock Service Endpoint to accelerate third party API integration development and testing.

Key updates include Calendar configuration for slots and event limits, and fixes for tabbed form validation, entity naming conflicts, and numeric attribute name parsing.

⚡ Performance Improvements

CMS Script Tokenizer Optimization

Enhanced tokenizer performance and memory efficiency across the framework. By optimizing the processing logic, we significantly reduced memory allocation and parsing time, particularly when processing large script files with extensive block comments.

Property Bag Escaping

Significant performance improvements for parsing and escaping large string values within Property Bags. The updated logic eliminates unnecessary string allocations during processing, resulting in much faster processing, and reduced memory usage.

Startup Optimization

Reduced initialization latency by enabling caching to initialize before the configuration is fully loaded. Previously, caching was deferred until configuration parsing completed, causing overhead on first load. The new approach initializes caching immediately, with custom caching configuration applied on subsequent calls when applicable. This provides a significant improvement in startup times across the board, especially for applications utilizing OAuth login.

🚀 New Features

Business Object Persist Status

Introduced bo.persistStatus() to retrieve the current persist status of a Business Object.

Additionally, the boPersistStatus type is now exposed, providing the following status values:

Status Description Persist Action
Clean Object was loaded or updated/inserted successfully Performs an UPDATE operation
New Object was newly created in memory Performs an INSERT operation
Deleted Object was deleted No action taken

This allows developers to programmatically determine the persist status of a Business Object.

Enabled support for navigation links within the calendar, allowing users to quickly navigate between views or dates directly.

Calendar Slot Configuration

Exposed slot duration and interval configuration for the calendar, giving developers finer control over how time slots are rendered and scheduled within the calendar view.

<@page/data/calendar
    ...
    slotDuration: '00:30:00'        // Specifies the frequency for displaying time slots
    slotMinTime: '00:00:00'         // Specifies the first time slot that will be displayed for each day
    slotMaxTime: '24:00:00'         // Specifies the last time slot that will be displayed for each day
    slotLabelFormat: <              // Specifies the text that will be displayed within a time slot
        hour: 'numeric'
        minute: '2-digit'
        omitZeroMinute: false()
        meridiem: 'short'
    >
>

Calendar Event Limit Configuration

Exposed event limit configuration for the calendar, enabling control over the maximum number of events displayed per day before collapsing into a "more" indicator.

<@page/data/calendar
    ...
    eventLimit: 5
>

Math Functions

Added isOdd() and isEven() functions to determine the parity of numeric values. These functions return true() only if the input is a whole integer matching the respective condition. Non-integer values (e.g. 2.5) return false() for both.

💻 CMS CLI and REPL

We have introduced a new cms.exe executable as part of the runtime, that transforms CaseMaster Script into a command line interface tool and interactive shell.

This addition enables developers to run scripts, evaluate expressions, and test logic directly from the terminal or within automated workflows.

Interactive REPL

You can launch an interactive Read-Eval-Print Loop by running cms.exe with no arguments. This mode provides a live environment for testing expressions, debugging logic, and exploring the expression language in real time without needing to write or save a script file.

Note: The REPL runs in an untrusted state by default to prevent accidental execution of privileged functions. It only operates in trusted mode when executed within a development environment.

Expression Evaluation

Execute single expressions using the -e flag. This is ideal for quick calculations, data transformations, or verifying logic snippets without the overhead of a full script file.

Example:

cms.exe -e "sum(1, 2, 3)"

Script and Function Execution

Run full .cms scripts or invoke specific functions within them directly from the terminal. Arguments passed after the script path are forwarded to the script as parameters.

By default the main function is invoked, but you can also invoke a specific function using the -f flag.

Example:

cms.exe "C:\app\script\process_data.cms" 100 "active"
cms.exe "C:\app\script\utils.cms" -f calculateTotal 50 20

Secure User Context

All execution modes (script, and expression evaluation) operate untrusted by default.

You can however execute any of the above modes under a specific user by providing credentials via the -u (email) and -p (password) flags. This ensures that scripts and expressions run with the exact permissions and data access rights of the target user.

Example:

cms.exe -u admin@example.com -p secret -e "user()"

📄 DOCX OpenXML Handler

We have massively expanded the DOCX handler from its original create, replace, saveAs and dispose foundations into a full document generation and manipulation engine. Developers can now programmatically build, modify, and merge DOCX files with fine grained control over structure and styling.

Declarative Qualifiers

Introducing <@docx/*> qualifiers, a declarative syntax for creating document elements concisely. Qualifiers are polymorphic, automatically wrapping input in the appropriate OpenXML structure, so developers can work without deep knowledge of paragraph, run, and text requirements. Raw XML strings and element objects are also supported for when lower level control is needed.

Table Construction & Styling

There is full support for building tables hierarchically (table > row > cell) with configurable widths (points, percentage, or auto) and a flexible border system supporting per side customization, preset styles (single, double, dashed, dotted, wave, thick, etc.), and default border toggling.

Path-Based Navigation

Elements can now be referenced and manipulated using a path expression syntax (body/1/1/1/1), enabling precise targeting of sections, tables, rows, and cells across body, header, and footer parts. This navigation system works similarly to the existing Word handler, providing a familiar experience. Element objects can also be stored and reused directly, improving performance over repeated path lookups.

Content Manipulation

We have added new functions for reading and modifying existing document content: * getText / setText can retrieve or update text within any element * removeElement can delete elements by path or object reference * addRow appends rows to existing tables * addElement with parent and index allows inserting content at specific positions

Images & Merging

  • addImage inserts PNG, JPG, GIF, or BMP images with optional pixel based resizing
  • Document merging (copybooks) can extract elements from one document and inject them into another, enabling template fragment reuse

Future Roadmap

This handler is currently in active development. While the core functionality for document creation, manipulation, and styling is now available, we have significant enhancements planned for upcoming releases. Expect further refinements to the qualifiers, additional options, and performance optimizations for handling large documents with extensive content.

🛠️ Mock Service Endpoint

We have introduced a new /service/mock endpoint designed to accelerate third party API integration development by allowing you to simulate API responses directly within CaseMaster.

Instead of relying on external mock services, waiting for backend services to be ready, or waiting for API keys/access etc. you can now define exactly how an endpoint should behave, including status codes and response data. This enables you to test your integrations in isolation, speeding up development and enabling better testing.

The endpoint intercepts requests and returns a simulated response based on your configuration. If no custom response is provided, it automatically echoes back the details of the incoming request (headers, body, query params, etc.), making it an excellent tool for debugging payload structures.

The easiest way to use the mock service is with the new <@url/service/mock> qualifier. This allows you to quickly generate service URLs with the required configuration, which can be used as drop in replacements for real API endpoints during development/testing.

<@url/service/mock
    status: 201                      // The HTTP status code to return
    delay: 1000                      // Simulate a 1 second network delay
    response: qualifier.invoke(      // Build the return response body using the JSON qualifier
        <@json
            status: 201,
            message: 'OK'
        >
    )
    log: true()                      // Log the full request/response to the application log
>

🐞 Fixes

Tabbed Edit Form Required Items

Resolved an issue where required field validation errors were not displayed when submitting a form containing an invalid input on an unfocused tab. Previously, the validation message triggered before the target tab finished focusing, causing the browser message to be missed. The fix now synchronizes the validation trigger with the tab activation event, ensuring that focus shifts to the correct field and the browser message appears reliably as soon as the tab content becomes visible.

Checklist Entity Naming Conflict

Fixed a naming conflict within the checklist refine function that occurred when the iterator entity was named entity. This update resolves the internal collision, allowing entity to be used safely as the iterator name without issue.

Numeric Attribute Names in Where Clauses

Fixed an issue where attribute names beginning with numeric characters caused parsing errors in where clauses.

Attribute Data Type Massaging

Corrected a critical logic error within the attribute data type massaging function boDesc.setAttrDataType() that previously prevented the function from being used.

Property Bag Pop Function

Fixed the pb.pop() function to correctly remove the last remaining item from a property bag. Previously, a bug prevented popping when only one item remained, returning null() and leaving the item untouched.