Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 14 additions & 16 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,27 @@ jobs:
strategy:
fail-fast: false
matrix:
cfengine: [ "boxlang-cfml@1", "lucee@5", "lucee@6", "adobe@2023", "adobe@2025" ]
coldboxVersion: [ "^7.0.0" ]
cfengine: [ "boxlang-cfml@1", "lucee@5", "lucee@6", "adobe@2023", "adobe@2025" ]
coldboxVersion: [ "^7.0.0", "^8.0.0" ]
experimental: [ false ]
# Experimental: ColdBox BE vs All Engines
include:
- coldboxVersion: "be"
cfengine: "lucee@5"
experimental: true
- coldboxVersion: "be"
cfengine: "lucee@6"
experimental: true
- coldboxVersion: "be"
cfengine: "adobe@2025"
cfengine: "adobe@2023"
experimental: true
- coldboxVersion: "be"
cfengine: "boxlang-cfml@1"
experimental: true
- coldboxVersion: "be"
cfengine: "boxlang@1"
# BoxLang PRIME with ColdBox 8
- coldboxVersion: "8"
cfengine: "boxlang-cfml@1"
experimental: true
# BoxLang CFML BE with ColdBox 8
- coldboxVersion: "8"
cfengine: "boxlang-cfml@be"
experimental: true
steps:
- name: Checkout Repository
Expand Down Expand Up @@ -88,16 +90,12 @@ jobs:
mkdir -p test-harness/tests/results
box testbox run --verbose outputFile=test-harness/tests/results/test-results outputFormats=json,antjunit

- name: Publish Test Reports
uses: mikepenz/action-junit-report@v5.6.2
- name: Publish Test Results
uses: EnricoMi/publish-unit-test-result-action@v2
if: always()
with:
report_paths: |
test-harness/tests/results/**/*.xml
check_name: "TestBox Report ${{ matrix.cfengine }}-${{ matrix.coldboxVersion }}"
include_passed: false
fail_on_failure: true
detailed_summary: true
junit_files: test-harness/tests/results/**/*.xml
check_name: "${{ matrix.cfengine }} ColdBox ${{ matrix.coldboxVersion }} Test Results"

- name: Upload Test Results to Artifacts
if: always()
Expand Down
2 changes: 1 addition & 1 deletion box.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name":"ColdBox Validation",
"author":"Ortus Solutions <info@ortussolutions.com>",
"version":"4.7.0",
"version":"4.8.0",
"location":"https://downloads.ortussolutions.com/ortussolutions/coldbox-modules/cbvalidation/@build.version@/cbvalidation-@build.version@.zip",
"slug":"cbvalidation",
"type":"modules",
Expand Down
7 changes: 7 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Fixed

- Copilot instructions added.
- Null values are now properly filtered out when `validateOrFail` returns validated struct/array results
- Handle null values correctly when filtering constraints in nested structures and arrays
- GitHub Actions workflow fixes

## [4.7.0] - 2025-10-13

### Changed
Expand Down
27 changes: 21 additions & 6 deletions models/ValidationManager.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -327,11 +327,16 @@ component accessors="true" serialize="false" singleton {
}

var constraint = arguments.constraints[ key ];
if ( constraint.keyExists( "items" ) || constraint.keyExists( "arrayItem" ) ) {
if (
( constraint.keyExists( "items" ) || constraint.keyExists( "arrayItem" ) ) && !isNull(
arguments.target[ key ]
) && isArray( arguments.target[ key ] )
) {
var items = arguments.target[ key ];
var filteredArray = [];
var arrayConstraints = ( constraint.keyExists( "items" ) ? constraint.items : constraint.arrayItem );
if ( arrayConstraints.keyExists( "constraints" ) || arrayConstraints.keyExists( "nestedConstraints" ) ) {
for ( var item in arguments.target[ key ] ) {
for ( var item in items ) {
if ( isStruct( item ) ) {
arrayAppend(
filteredArray,
Expand All @@ -345,18 +350,28 @@ component accessors="true" serialize="false" singleton {
}
}
} else {
filteredArray = arguments.target[ key ];
filteredArray = isNull( arguments.target[ key ] ) ? javacast( "null", "" ) : arguments.target[
key
];
}
filteredTarget[ key ] = filteredArray;
} else if ( constraint.keyExists( "constraints" ) || constraint.keyExists( "nestedConstraints" ) ) {
if ( !isNull( filteredArray ) ) {
filteredTarget[ key ] = filteredArray;
}
} else if (
( constraint.keyExists( "constraints" ) || constraint.keyExists( "nestedConstraints" ) ) && !isNull(
arguments.target[ key ]
) && isStruct( arguments.target[ key ] )
) {
filteredTarget[ key ] = filterTargetForConstraints(
target = arguments.target[ key ],
constraints = (
constraint.keyExists( "constraints" ) ? constraint.constraints : constraint.nestedConstraints
)
);
} else {
filteredTarget[ key ] = arguments.target[ key ];
if ( !isNull( arguments.target[ key ] ) ) {
filteredTarget[ key ] = arguments.target[ key ];
}
}
}
return filteredTarget;
Expand Down
12 changes: 8 additions & 4 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Apache License, Version 2.0.

- **BoxLang** 1.0+ (Preferred)
- **Lucee** 5.x+
- **Adobe ColdFusion** 2021+
- **Adobe ColdFusion** 2023+
- **Dependencies**: ColdBox 7+, cbi18n 3.0+

## Installation
Expand All @@ -46,7 +46,11 @@ box install cbvalidation

The module will register several objects into WireBox using the `@cbvalidation` namespace. The validation manager is registered as `ValidationManager@cbvalidation`. It will also register several helper methods that can be used throughout the ColdBox application: `validate(), validateOrFail(), getValidationManager()`

### WireBox Registrations
## Documentation

This module is fully documented at: https://coldbox-validation.ortusbooks.com/. It also has an MCP server with live docs and examples.

## WireBox Registrations

- `ValidationManager@cbvalidation` - The core validation engine
- `validationManager@cbvalidation` - Alias for convenience
Expand Down Expand Up @@ -348,7 +352,7 @@ www.coldbox.org | www.luismajano.com | www.ortussolutions.com
********************************************************************************
```

### HONOR GOES TO GOD ABOVE ALL
## HONOR GOES TO GOD ABOVE ALL

Because of His grace, this project exists. If you don't like this, then don't read it, its not for you.

Expand All @@ -358,6 +362,6 @@ And not only so, but we glory in tribulations also: knowing that tribulation wor
And patience, experience; and experience, hope:
And hope maketh not ashamed; because the love of God is shed abroad in our hearts by the Holy Ghost which is given unto us. ." Romans 5:5

### THE DAILY BREAD
## THE DAILY BREAD

> "I am the way, and the truth, and the life; no one comes to the Father, but by me (JESUS)" Jn 14:1-12
32 changes: 32 additions & 0 deletions server-boxlang-cfml@be.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"name":"cbvalidation-boxlang-cfml@be",
"app":{
"serverHomeDirectory":".engine/boxlang-cfml-be",
"cfengine":"boxlang@be"
},
"web":{
"http":{
"port":"60299"
},
"rewrites":{
"enable":true
},
"webroot":"test-harness",
"aliases":{
"/moduleroot/cbvalidation":"../"
}
},
"JVM":{
"heapSize":"1024",
"javaVersion":"openjdk21_jre",
"args":"-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8888"
},
"openBrowser": false,
"cfconfig":{
"file":".cfconfig.json"
},
"env":{},
"scripts":{
"onServerInitialInstall":"install bx-compat-cfml,bx-esapi,bx-mysql --noSave"
}
}
Loading