diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 37dcbbb..e2cde00 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -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 @@ -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() diff --git a/box.json b/box.json index 0a698ac..8e17938 100644 --- a/box.json +++ b/box.json @@ -1,7 +1,7 @@ { "name":"ColdBox Validation", "author":"Ortus Solutions ", - "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", diff --git a/changelog.md b/changelog.md index c9a6b20..7748e5e 100644 --- a/changelog.md +++ b/changelog.md @@ -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 diff --git a/models/ValidationManager.cfc b/models/ValidationManager.cfc index 34d65d8..469e009 100644 --- a/models/ValidationManager.cfc +++ b/models/ValidationManager.cfc @@ -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, @@ -345,10 +350,18 @@ 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 = ( @@ -356,7 +369,9 @@ component accessors="true" serialize="false" singleton { ) ); } else { - filteredTarget[ key ] = arguments.target[ key ]; + if ( !isNull( arguments.target[ key ] ) ) { + filteredTarget[ key ] = arguments.target[ key ]; + } } } return filteredTarget; diff --git a/readme.md b/readme.md index ce292d3..38c99a5 100644 --- a/readme.md +++ b/readme.md @@ -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 @@ -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 @@ -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. @@ -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 diff --git a/server-boxlang-cfml@be.json b/server-boxlang-cfml@be.json new file mode 100644 index 0000000..19cb4a4 --- /dev/null +++ b/server-boxlang-cfml@be.json @@ -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" + } +}