{"id":112,"date":"2026-05-25T11:17:19","date_gmt":"2026-05-25T09:17:19","guid":{"rendered":"https:\/\/www.visualdomain.ch\/?p=112"},"modified":"2026-08-15T11:59:23","modified_gmt":"2026-08-15T09:59:23","slug":"foo","status":"publish","type":"post","link":"https:\/\/www.visualdomain.ch\/?p=112","title":{"rendered":"Aria Automation input validation"},"content":{"rendered":"\r\n<div class=\"align wp-block-table-of-content-block-table-of-content\" id='tbcnbBlock-1' data-attributes='{&quot;isNested&quot;:true,&quot;header&quot;:{&quot;bgColor&quot;:&quot;rgba(27, 27, 27, 1)&quot;,&quot;textColor&quot;:&quot;#444&quot;,&quot;iconColor&quot;:&quot;rgba(203, 203, 203, 1)&quot;,&quot;separatorWidth&quot;:1,&quot;separatorColor&quot;:&quot;#ccc&quot;,&quot;txtColor&quot;:&quot;rgba(203, 203, 203, 1)&quot;},&quot;headings&quot;:[{&quot;contents&quot;:&quot;Introduction&quot;,&quot;tag&quot;:&quot;H2&quot;,&quot;id&quot;:&quot;bppb-heading-anchor-1&quot;},{&quot;contents&quot;:&quot;The Problem with Imperative Validation&quot;,&quot;tag&quot;:&quot;H2&quot;,&quot;id&quot;:&quot;bppb-heading-anchor-2&quot;},{&quot;contents&quot;:&quot;A Declarative Approach&quot;,&quot;tag&quot;:&quot;H2&quot;,&quot;id&quot;:&quot;bppb-heading-anchor-3&quot;},{&quot;contents&quot;:&quot;Validating Arrays&quot;,&quot;tag&quot;:&quot;H2&quot;,&quot;id&quot;:&quot;bppb-heading-anchor-4&quot;},{&quot;contents&quot;:&quot;Type Handling and Port Ranges&quot;,&quot;tag&quot;:&quot;H2&quot;,&quot;id&quot;:&quot;bppb-heading-anchor-5&quot;},{&quot;contents&quot;:&quot;Dynamic Policy Values&quot;,&quot;tag&quot;:&quot;H2&quot;,&quot;id&quot;:&quot;bppb-heading-anchor-6&quot;},{&quot;contents&quot;:&quot;Integration in Aria Orchestrator&quot;,&quot;tag&quot;:&quot;H2&quot;,&quot;id&quot;:&quot;bppb-heading-anchor-7&quot;},{&quot;contents&quot;:&quot;Workflow&quot;,&quot;tag&quot;:&quot;H2&quot;,&quot;id&quot;:&quot;bppb-heading-anchor-8&quot;},{&quot;contents&quot;:&quot;Custom Form&quot;,&quot;tag&quot;:&quot;H2&quot;,&quot;id&quot;:&quot;bppb-heading-anchor-9&quot;},{&quot;contents&quot;:&quot;AI Disclosure&quot;,&quot;tag&quot;:&quot;H2&quot;,&quot;id&quot;:&quot;bppb-heading-anchor-10&quot;},{&quot;contents&quot;:&quot;0 responses to \\&quot;Aria Automation input validation\\&quot;&quot;,&quot;tag&quot;:&quot;H2&quot;,&quot;id&quot;:&quot;bppb-heading-anchor-11&quot;}],&quot;boxList&quot;:{&quot;txtStyle&quot;:&quot;normal&quot;,&quot;nTxtColor&quot;:&quot;rgba(203, 203, 203, 1)&quot;,&quot;nBarColor&quot;:&quot;#b0aeb1&quot;,&quot;hTxtColor&quot;:&quot;#ec1e75&quot;,&quot;hBarColor&quot;:&quot;#ec1e75&quot;,&quot;nTxtDecoration&quot;:false,&quot;hTxtDecoration&quot;:false,&quot;dotSize&quot;:15,&quot;panelHeight&quot;:0,&quot;treeColor&quot;:&quot;blueviolet&quot;,&quot;dotShadow&quot;:[{&quot;hOffset&quot;:&quot;1px&quot;,&quot;vOffset&quot;:&quot;1px&quot;,&quot;blur&quot;:&quot;5px&quot;,&quot;spreed&quot;:&quot;1px&quot;,&quot;color&quot;:&quot;#b3b3b3&quot;,&quot;isInset&quot;:false}],&quot;maxHeight&quot;:{&quot;desktop&quot;:0,&quot;tablet&quot;:0,&quot;mobile&quot;:0},&quot;padding&quot;:{&quot;desktop&quot;:{&quot;top&quot;:&quot;0px&quot;,&quot;bottom&quot;:&quot;0px&quot;,&quot;left&quot;:&quot;20px&quot;,&quot;right&quot;:&quot;0px&quot;},&quot;tablet&quot;:{&quot;top&quot;:&quot;0px&quot;,&quot;bottom&quot;:&quot;0px&quot;,&quot;left&quot;:&quot;20px&quot;,&quot;right&quot;:&quot;0px&quot;},&quot;mobile&quot;:{&quot;top&quot;:&quot;0px&quot;,&quot;bottom&quot;:&quot;0px&quot;,&quot;left&quot;:&quot;20px&quot;,&quot;right&quot;:&quot;0px&quot;}}},&quot;title&quot;:{&quot;text&quot;:&quot;Table of Contents&quot;,&quot;tag&quot;:&quot;h2&quot;},&quot;markup&quot;:{&quot;view&quot;:&quot;decimal&quot;,&quot;icon&quot;:false,&quot;color&quot;:&quot;rgba(0, 0, 0, 0)&quot;,&quot;markupSize&quot;:{&quot;desktop&quot;:&quot;16px&quot;,&quot;tablet&quot;:&quot;16px&quot;,&quot;mobile&quot;:&quot;16px&quot;}},&quot;advanced&quot;:{&quot;dimension&quot;:{&quot;padding&quot;:{&quot;desktop&quot;:{&quot;top&quot;:&quot;0px&quot;,&quot;right&quot;:&quot;0px&quot;,&quot;bottom&quot;:&quot;0px&quot;,&quot;left&quot;:&quot;0px&quot;},&quot;tablet&quot;:{&quot;top&quot;:&quot;0px&quot;,&quot;right&quot;:&quot;0px&quot;,&quot;bottom&quot;:&quot;0px&quot;,&quot;left&quot;:&quot;0px&quot;},&quot;mobile&quot;:{&quot;top&quot;:&quot;0px&quot;,&quot;right&quot;:&quot;0px&quot;,&quot;bottom&quot;:&quot;0px&quot;,&quot;left&quot;:&quot;0px&quot;}}},&quot;borderShadow&quot;:{&quot;normal&quot;:{&quot;radius&quot;:{&quot;top&quot;:&quot;0px&quot;,&quot;right&quot;:&quot;0px&quot;,&quot;bottom&quot;:&quot;0px&quot;,&quot;left&quot;:&quot;0px&quot;},&quot;shadow&quot;:[{&quot;hOffset&quot;:&quot;0px&quot;,&quot;vOffset&quot;:&quot;0px&quot;,&quot;blur&quot;:&quot;0px&quot;,&quot;spreed&quot;:&quot;0px&quot;,&quot;color&quot;:&quot;#7090b0&quot;,&quot;isInset&quot;:false}]}},&quot;background&quot;:{&quot;normal&quot;:{&quot;type&quot;:&quot;color&quot;,&quot;color&quot;:&quot;rgba(27, 27, 27, 1)&quot;,&quot;gradient&quot;:{&quot;type&quot;:&quot;radial&quot;,&quot;radialType&quot;:&quot;ellipse&quot;,&quot;colors&quot;:[{&quot;color&quot;:&quot;rgba(58, 66, 222, 1)&quot;,&quot;position&quot;:&quot;0&quot;},{&quot;color&quot;:&quot;rgba(176, 195, 235, 1)&quot;,&quot;position&quot;:&quot;80&quot;}],&quot;centerPositions&quot;:{&quot;x&quot;:50,&quot;y&quot;:50},&quot;angel&quot;:90},&quot;img&quot;:{&quot;url&quot;:&quot;&quot;,&quot;desktop&quot;:{&quot;position&quot;:&quot;center center&quot;,&quot;xPosition&quot;:0,&quot;yPosition&quot;:0,&quot;attachment&quot;:&quot;&quot;,&quot;repeat&quot;:&quot;no-repeat&quot;,&quot;size&quot;:&quot;&quot;,&quot;customSize&quot;:&quot;0px&quot;},&quot;tablet&quot;:{&quot;position&quot;:&quot;center center&quot;,&quot;xPosition&quot;:0,&quot;yPosition&quot;:0,&quot;attachment&quot;:&quot;&quot;,&quot;repeat&quot;:&quot;no-repeat&quot;,&quot;size&quot;:&quot;&quot;,&quot;customSize&quot;:&quot;0px&quot;},&quot;mobile&quot;:{&quot;position&quot;:&quot;center center&quot;,&quot;xPosition&quot;:0,&quot;yPosition&quot;:0,&quot;attachment&quot;:&quot;&quot;,&quot;repeat&quot;:&quot;no-repeat&quot;,&quot;size&quot;:&quot;&quot;,&quot;customSize&quot;:&quot;0px&quot;}},&quot;video&quot;:{&quot;url&quot;:&quot;&quot;,&quot;loop&quot;:false},&quot;transition&quot;:0.3},&quot;overlay&quot;:{&quot;isEnabled&quot;:false,&quot;colors&quot;:{&quot;type&quot;:&quot;color&quot;,&quot;color&quot;:&quot;rgba(27, 27, 27, 1)&quot;}}},&quot;responsive&quot;:{&quot;mobile&quot;:true},&quot;css&quot;:&quot;&quot;},&quot;align&quot;:&quot;&quot;,&quot;rendered&quot;:true,&quot;tagName&quot;:[&quot;h1&quot;,&quot;h2&quot;,&quot;h3&quot;],&quot;minimize&quot;:{&quot;toggle&quot;:true,&quot;expandIcon&quot;:&quot;fa-solid fa-chevron-down&quot;,&quot;collapseIcon&quot;:&quot;fa-solid fa-chevron-up&quot;},&quot;theme&quot;:&quot;default&quot;,&quot;sticky&quot;:{&quot;toggle&quot;:false,&quot;device&quot;:[&quot;Desktop&quot;],&quot;width&quot;:{&quot;desktop&quot;:&quot;617px&quot;,&quot;tablet&quot;:&quot;90%&quot;,&quot;mobile&quot;:&quot;100%&quot;},&quot;horizonAlign&quot;:&quot;left&quot;,&quot;verticalAlign&quot;:&quot;top&quot;,&quot;right&quot;:{&quot;desktop&quot;:&quot;0px&quot;,&quot;tablet&quot;:&quot;0px&quot;,&quot;mobile&quot;:&quot;0px&quot;},&quot;left&quot;:{&quot;desktop&quot;:&quot;0px&quot;,&quot;tablet&quot;:&quot;0px&quot;,&quot;mobile&quot;:&quot;0px&quot;},&quot;top&quot;:{&quot;desktop&quot;:&quot;0px&quot;,&quot;tablet&quot;:&quot;0px&quot;,&quot;mobile&quot;:&quot;0px&quot;},&quot;bottom&quot;:{&quot;desktop&quot;:&quot;0px&quot;,&quot;tablet&quot;:&quot;0px&quot;,&quot;mobile&quot;:&quot;0px&quot;},&quot;zIndex&quot;:{&quot;desktop&quot;:100,&quot;tablet&quot;:100,&quot;mobile&quot;:100}},&quot;slideTitle&quot;:{&quot;titleColor&quot;:&quot;#2e2e2e&quot;,&quot;slideBarColor&quot;:&quot;#abababbf&quot;,&quot;spaceDevice&quot;:&quot;desktop&quot;,&quot;space&quot;:{&quot;desktop&quot;:&quot;15px&quot;,&quot;tablet&quot;:&quot;15px&quot;,&quot;mobile&quot;:&quot;15px&quot;},&quot;spaceBottomDevice&quot;:&quot;desktop&quot;,&quot;spaceBottom&quot;:{&quot;desktop&quot;:&quot;15px&quot;,&quot;tablet&quot;:&quot;15px&quot;,&quot;mobile&quot;:&quot;15px&quot;},&quot;spaceBottomUnit&quot;:{&quot;desktop&quot;:&quot;px&quot;,&quot;tablet&quot;:&quot;px&quot;,&quot;mobile&quot;:&quot;px&quot;}},&quot;slideList&quot;:{&quot;spaceDevice&quot;:&quot;desktop&quot;,&quot;space&quot;:{&quot;desktop&quot;:&quot;15px&quot;,&quot;tablet&quot;:&quot;15px&quot;,&quot;mobile&quot;:&quot;15px&quot;},&quot;typo&quot;:{&quot;fontSize&quot;:{&quot;desktop&quot;:&quot;16px&quot;,&quot;tablet&quot;:&quot;&quot;,&quot;mobile&quot;:&quot;&quot;}},&quot;fontSize&quot;:{&quot;desktop&quot;:&quot;16px&quot;,&quot;tablet&quot;:&quot;16px&quot;,&quot;mobile&quot;:&quot;16px&quot;},&quot;fontUnit&quot;:{&quot;desktop&quot;:&quot;px&quot;,&quot;tablet&quot;:&quot;px&quot;,&quot;mobile&quot;:&quot;px&quot;}}}'><\/div>\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-794e3cfa wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\"><\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\"><\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\"><div class=\"has-text-align-right wp-block-post-date__modified-date wp-block-post-date\"><time datetime=\"2026-08-15T11:59:23+02:00\">15.08.2026<\/time><\/div><\/div>\n<\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><span id=\"bppb-heading-anchor-1\"><\/span>Introduction<\/h2>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\" style=\"border-top-left-radius:6px;border-top-right-radius:6px;border-bottom-left-radius:6px;border-bottom-right-radius:6px\">Input validation in VMware Aria Automation and VMware Aria Orchestrator often starts simple.<\/p>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\">A virtual disk must be between 10 and 2000 GB.<br>A CPU value must be one of a few allowed options.<br>A list of TCP ports must stay within an approved range.<\/p>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\">At first, this is easy to solve with imperative validation code. But as the number of inputs grows, validation logic quickly becomes repetitive, harder to read, and harder to reuse across custom form actions and workflows.<\/p>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\">This is the problem I wanted to solve with a small policy-based validation framework for Aria Orchestrator.<\/p>\n\n\n\n<div class=\"wp-block-group has-global-padding is-layout-constrained wp-block-group-is-layout-constrained\">\n<p class=\"is-style-default highlight-box ticss-62093dae has-accent-5-background-color has-background has-medium-font-size wp-block-paragraph\" style=\"border-top-left-radius:5px;border-top-right-radius:5px;border-bottom-left-radius:5px;border-bottom-right-radius:5px;padding-top:var(--wp--preset--spacing--20);padding-right:var(--wp--preset--spacing--30);padding-bottom:var(--wp--preset--spacing--20);padding-left:var(--wp--preset--spacing--30)\">The idea is simple:<br>Instead of writing validation logic again and again, define validation rules declaratively in a policy and let a reusable validator do the work.<\/p>\n<\/div>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\">The code and the full policy reference are available on GitHub:<br>GitHub: <a href=\"https:\/\/github.com\/viscop\/aria-dto-validator\">https:\/\/github.com\/viscop\/aria-dto-validator<\/a><\/p>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\">This article does not try to document every option of the validator. The goal is to explain the problem, show the basic usage pattern, and demonstrate why the same validation should run both in the form action and inside the workflow.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The Problem with Imperative Validation<\/h2>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\">A typical validation action may start with something simple like this:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>var message = \"\";\n\nif (diskSize >= 10 &amp;&amp; diskSize &lt;= 2000) {\n  return message;\n}\n\nmessage = \"Disk size is not between 10 and 2000\";\nreturn message;<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">message<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #CE9178\">&quot;&quot;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">diskSize<\/span><span style=\"color: #D4D4D4\"> &gt;= <\/span><span style=\"color: #B5CEA8\">10<\/span><span style=\"color: #D4D4D4\"> &amp;&amp; <\/span><span style=\"color: #9CDCFE\">diskSize<\/span><span style=\"color: #D4D4D4\"> &lt;= <\/span><span style=\"color: #B5CEA8\">2000<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">message<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">message<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #CE9178\">&quot;Disk size is not between 10 and 2000&quot;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">message<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\">For a single field, this is still easy to understand.<\/p>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\">But real-world forms usually contain more than one input. You may need to validate strings, numbers, arrays, port ranges, required fields, allowed values, naming conventions, and dependencies between fields.<\/p>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\">Over time, this often leads to duplicated code, slightly different validation logic in different places, and a higher cognitive load for everyone who has to maintain the workflow.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">A Declarative Approach<\/h2>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\">Instead of spreading validation logic across multiple actions and workflows, the validation rules can be described in a policy.<\/p>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\">A policy is easier to read, easier to reuse, and easier to extend.<\/p>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\">Here is a small example:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>var policy = [\n  {\n    path: \"hostname\",\n    type: \"string\",\n    minLength: 3,\n    maxLength: 30,\n    regex: \"^&#91;a-z0-9-&#93;+$\",\n    onMissing: \"fail\",\n    errorMessage: \"Hostname is invalid.\"\n  },\n  {\n    path: \"cpu\",\n    type: \"number\",\n    integerOnly: true,\n    allowedValues: &#91;2, 4, 8&#93;,\n    onMissing: \"fail\",\n    errorMessage: \"CPU must be 2, 4, or 8.\"\n  },\n  {\n    path: \"ports&#91;*&#93;\",\n    type: \"number\",\n    allowedValues: &#91;\"80\", \"443\", \"8443-8445\"&#93;,\n    onMissing: \"fail\",\n    errorMessage: \"One or more ports are not allowed.\"\n  }\n];<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">policy<\/span><span style=\"color: #D4D4D4\"> = [<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">path:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;hostname&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">type:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;string&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">minLength:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">3<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">maxLength:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">30<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">regex:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;^&#91;a-z0-9-&#93;+$&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">onMissing:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;fail&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">errorMessage:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;Hostname is invalid.&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  },<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">path:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;cpu&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">type:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;number&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">integerOnly:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">true<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">allowedValues:<\/span><span style=\"color: #D4D4D4\"> &#91;<\/span><span style=\"color: #B5CEA8\">2<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">4<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">8<\/span><span style=\"color: #D4D4D4\">&#93;,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">onMissing:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;fail&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">errorMessage:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;CPU must be 2, 4, or 8.&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  },<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">path:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;ports&#91;*&#93;&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">type:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;number&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">allowedValues:<\/span><span style=\"color: #D4D4D4\"> &#91;<\/span><span style=\"color: #CE9178\">&quot;80&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&quot;443&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&quot;8443-8445&quot;<\/span><span style=\"color: #D4D4D4\">&#93;,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">onMissing:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;fail&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">errorMessage:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;One or more ports are not allowed.&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">];<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\">This policy validates three inputs:<\/p>\n\n\n\n<ul class=\"wp-block-list has-medium-font-size\">\n<li>hostname<\/li>\n\n\n\n<li>cpu<\/li>\n\n\n\n<li>ports<\/li>\n<\/ul>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\">The validation logic itself is handled by the framework:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>var result = System.getModule(\"ch.org.security.validation\").validateDto(\n    policy,\n    inputDto,\n    null\n);\n\nreturn result;<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">result<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">System<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">getModule<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;ch.org.security.validation&quot;<\/span><span style=\"color: #D4D4D4\">).<\/span><span style=\"color: #DCDCAA\">validateDto<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">policy<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">inputDto<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">null<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">result<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\">A successful validation result looks like this:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>{\n  valid: true,\n  errors: [],\n  warnings: []\n}<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D4D4D4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #C8C8C8\">valid<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #569CD6\">true<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #C8C8C8\">errors<\/span><span style=\"color: #D4D4D4\">: [],<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #C8C8C8\">warnings<\/span><span style=\"color: #D4D4D4\">: []<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\">If validation fails, <code>valid<\/code> is set to <code>false<\/code> and the <code>errors<\/code> array contains the validation messages.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Validating Arrays<\/h2>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\">One useful feature is array validation.<br>If a property contains an array, the path can use <code>[*]<\/code>:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>path: \"ports&#91;*&#93;\"<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D4D4D4\">path: <\/span><span style=\"color: #CE9178\">&quot;ports&#91;*&#93;&quot;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\">This means that each item in the array is validated against the rule.<\/p>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\">For example, this DTO is valid:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>{\n  hostname: \"test123\",\n  cpu: 4,\n  ports: &#91;\"80\", \"443\"&#93;\n}<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D4D4D4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #C8C8C8\">hostname<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;test123&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #C8C8C8\">cpu<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #B5CEA8\">4<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #C8C8C8\">ports<\/span><span style=\"color: #D4D4D4\">: &#91;<\/span><span style=\"color: #CE9178\">&quot;80&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&quot;443&quot;<\/span><span style=\"color: #D4D4D4\">&#93;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\">This DTO is not valid:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>{\n  hostname: \"TEST_123\",\n  cpu: 6,\n  ports: &#91;\"80\", \"1234\"&#93;\n}<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D4D4D4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #C8C8C8\">hostname<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;TEST_123&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #C8C8C8\">cpu<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #B5CEA8\">6<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #C8C8C8\">ports<\/span><span style=\"color: #D4D4D4\">: &#91;<\/span><span style=\"color: #CE9178\">&quot;80&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&quot;1234&quot;<\/span><span style=\"color: #D4D4D4\">&#93;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\">Possible validation errors could be:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>Hostname is invalid.\nCPU must be 2, 4, or 8.\nOne or more ports are not allowed.<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D4D4D4\">Hostname is invalid.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">CPU must be <\/span><span style=\"color: #B5CEA8\">2<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">4<\/span><span style=\"color: #D4D4D4\">, or <\/span><span style=\"color: #B5CEA8\">8<\/span><span style=\"color: #D4D4D4\">.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">One or more ports are not allowed.<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Type Handling and Port Ranges<\/h2>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\">In many form scenarios, values arrive as strings even if they represent numbers.<\/p>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\">For example, TCP ports may come from the form as a string array:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>{\n  ports: &#91;\"80\", \"443\"&#93;\n}<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D4D4D4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #C8C8C8\">ports<\/span><span style=\"color: #D4D4D4\">: &#91;<\/span><span style=\"color: #CE9178\">&quot;80&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&quot;443&quot;<\/span><span style=\"color: #D4D4D4\">&#93;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\">The policy can still explicitly validate the values as numbers:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>{\n  path: \"ports&#91;*&#93;\",\n  type: \"number\",\n  allowedValues: &#91;\"80\", \"443\", \"8443-8445\"&#93;,\n  onMissing: \"fail\",\n  errorMessage: \"One or more ports are not allowed.\"\n}<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D4D4D4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #C8C8C8\">path<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;ports&#91;*&#93;&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #C8C8C8\">type<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;number&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #C8C8C8\">allowedValues<\/span><span style=\"color: #D4D4D4\">: &#91;<\/span><span style=\"color: #CE9178\">&quot;80&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&quot;443&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&quot;8443-8445&quot;<\/span><span style=\"color: #D4D4D4\">&#93;,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #C8C8C8\">onMissing<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;fail&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #C8C8C8\">errorMessage<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;One or more ports are not allowed.&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\">The allowed values can also contain ranges: 8443-8445<\/p>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\">This means that the following values are allowed: 8443, 8444 and 8445<\/p>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\">This removes the need for repetitive nested loop logic and keeps the validation policy compact and readable.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Dynamic Policy Values<\/h2>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\">The policy does not have to be limited to static values.<\/p>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\">Because policies are plain JavaScript objects, selected values can be built dynamically before the validator is called. This makes the framework much more flexible, because validation rules can depend on runtime context.<\/p>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\">For example:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>var allowedEnvironments = &#91;\"dev\", \"test\", \"prod\"&#93;;\n\nfunction getAllowedMemorySizes(environment) {\n    if (environment === \"prod\") {\n        return &#91;8, 16, 32, 64&#93;;\n    }\n\n    if (environment === \"test\") {\n        return &#91;4, 8, 16&#93;;\n    }\n\n    return &#91;2, 4, 8&#93;;\n}\n\nvar environment = userDTO.environment;\n\nvar policy = &#91;\n  {\n    path: \"environment\",\n    type: \"string\",\n    allowedValues: allowedEnvironments,\n    onMissing: \"fail\",\n    errorMessage: \"Environment is not allowed.\"\n  },\n  {\n    path: \"memoryGb\",\n    type: \"number\",\n    integerOnly: true,\n    allowedValues: getAllowedMemorySizes(environment),\n    onMissing: \"fail\",\n    errorMessage: \"Memory size is not allowed for this environment.\"\n  }\n&#93;;<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">allowedEnvironments<\/span><span style=\"color: #D4D4D4\"> = &#91;<\/span><span style=\"color: #CE9178\">&quot;dev&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&quot;test&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&quot;prod&quot;<\/span><span style=\"color: #D4D4D4\">&#93;;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">function<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">getAllowedMemorySizes<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">environment<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">environment<\/span><span style=\"color: #D4D4D4\"> === <\/span><span style=\"color: #CE9178\">&quot;prod&quot;<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> &#91;<\/span><span style=\"color: #B5CEA8\">8<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">16<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">32<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">64<\/span><span style=\"color: #D4D4D4\">&#93;;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">environment<\/span><span style=\"color: #D4D4D4\"> === <\/span><span style=\"color: #CE9178\">&quot;test&quot;<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> &#91;<\/span><span style=\"color: #B5CEA8\">4<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">8<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">16<\/span><span style=\"color: #D4D4D4\">&#93;;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> &#91;<\/span><span style=\"color: #B5CEA8\">2<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">4<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">8<\/span><span style=\"color: #D4D4D4\">&#93;;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">environment<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">userDTO<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">environment<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">policy<\/span><span style=\"color: #D4D4D4\"> = &#91;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">path:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;environment&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">type:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;string&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">allowedValues:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">allowedEnvironments<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">onMissing:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;fail&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">errorMessage:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;Environment is not allowed.&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  },<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">path:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;memoryGb&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">type:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;number&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">integerOnly:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">true<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">allowedValues:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">getAllowedMemorySizes<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">environment<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">onMissing:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;fail&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">errorMessage:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;Memory size is not allowed for this environment.&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">&#93;;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\">This allows policies to use values from different sources, for example:<\/p>\n\n\n\n<ul class=\"wp-block-list has-medium-font-size\">\n<li>Project context<\/li>\n\n\n\n<li>User context<\/li>\n\n\n\n<li>Configuration data<\/li>\n\n\n\n<li>A database<\/li>\n\n\n\n<li>A REST API<\/li>\n\n\n\n<li>A CMDB<\/li>\n\n\n\n<li>A custom registry<\/li>\n\n\n\n<li>Another Aria Orchestrator action<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><span id=\"bppb-heading-anchor-7\"><\/span>Integration in Aria Orchestrator<\/h2>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\">For the example setup, I use a few Aria Orchestrator actions.<br>The exact module structure can be adapted to your own environment.<\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-794e3cfa wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:100%\">\n<div class=\"wp-block-group has-global-padding is-layout-constrained wp-block-group-is-layout-constrained\">\n<figure style=\"margin-top:var(--wp--preset--spacing--20);margin-right:0;margin-bottom:var(--wp--preset--spacing--20);margin-left:0;padding-top:0;padding-right:0;padding-bottom:0;padding-left:0;line-height:1\" class=\"wp-block-table has-medium-font-size\"><table class=\"has-fixed-layout\" style=\"border-width:1px\"><thead><tr><th class=\"has-text-align-left\" data-align=\"left\">Action<\/th><th class=\"has-text-align-left\" data-align=\"left\">Purpose<\/th><\/tr><\/thead><tbody><tr><td class=\"has-text-align-left\" data-align=\"left\">buildInputDto<\/td><td class=\"has-text-align-left\" data-align=\"left\">Builds a DTO from multiple custom form fields. Mainly used by the custom form action.<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">evaluateExamplePolicy<\/td><td class=\"has-text-align-left\" data-align=\"left\">Contains or returns the business-specific validation policy.<br><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">validateInput<\/td><td class=\"has-text-align-left\" data-align=\"left\">Wrapper action used by both form validation and workflow validation.<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">validateDto<\/td><td class=\"has-text-align-left\" data-align=\"left\">Core framework action that validates a DTO against a policy.<\/td><\/tr><\/tbody><\/table><\/figure>\n<\/div>\n<\/div>\n<\/div>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\">Only <code>validateDto<\/code> is the generic framework part.<\/p>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\">The other actions are integration examples and can be adapted to match your own naming conventions, module structure, or workflow design.<\/p>\n\n\n\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;6ac46c44e8df7&quot;}\" data-wp-interactive=\"core\/image\" data-wp-key=\"6ac46c44e8df7\" class=\"wp-block-image size-full wp-lightbox-container\"><img loading=\"lazy\" decoding=\"async\" width=\"1056\" height=\"421\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on--click=\"actions.showLightbox\" data-wp-on--load=\"callbacks.setButtonStyles\" data-wp-on--pointerdown=\"actions.preloadImage\" data-wp-on--pointerenter=\"actions.preloadImageWithDelay\" data-wp-on--pointerleave=\"actions.cancelPreload\" data-wp-on-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/www.visualdomain.ch\/wp-content\/uploads\/2026\/05\/image.png\" alt=\"\" class=\"wp-image-46\" srcset=\"https:\/\/www.visualdomain.ch\/wp-content\/uploads\/2026\/05\/image.png 1056w, https:\/\/www.visualdomain.ch\/wp-content\/uploads\/2026\/05\/image-300x120.png 300w, https:\/\/www.visualdomain.ch\/wp-content\/uploads\/2026\/05\/image-1024x408.png 1024w, https:\/\/www.visualdomain.ch\/wp-content\/uploads\/2026\/05\/image-768x306.png 768w\" sizes=\"auto, (max-width: 1056px) 100vw, 1056px\" \/><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\tdata-wp-bind--aria-label=\"state.thisImage.triggerButtonAriaLabel\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.thisImage.buttonRight\"\n\t\t\tdata-wp-style--top=\"state.thisImage.buttonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><figcaption class=\"wp-element-caption\">buildInputDto<\/figcaption><\/figure>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>var inputDto = {\n    hostname : hostname,\n    cpu : cpu,\n    ports : ports    \n}\n\nreturn JSON.stringify(inputDto);<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">inputDto<\/span><span style=\"color: #D4D4D4\"> = {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">hostname :<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">hostname<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">cpu :<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">cpu<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">ports :<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">ports<\/span><span style=\"color: #D4D4D4\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">JSON<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">stringify<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">inputDto<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;6ac46c44e943c&quot;}\" data-wp-interactive=\"core\/image\" data-wp-key=\"6ac46c44e943c\" class=\"wp-block-image size-large wp-lightbox-container\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"462\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on--click=\"actions.showLightbox\" data-wp-on--load=\"callbacks.setButtonStyles\" data-wp-on--pointerdown=\"actions.preloadImage\" data-wp-on--pointerenter=\"actions.preloadImageWithDelay\" data-wp-on--pointerleave=\"actions.cancelPreload\" data-wp-on-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/www.visualdomain.ch\/wp-content\/uploads\/2026\/05\/image-2-1024x462.png\" alt=\"\" class=\"wp-image-48\" srcset=\"https:\/\/www.visualdomain.ch\/wp-content\/uploads\/2026\/05\/image-2-1024x462.png 1024w, https:\/\/www.visualdomain.ch\/wp-content\/uploads\/2026\/05\/image-2-300x135.png 300w, https:\/\/www.visualdomain.ch\/wp-content\/uploads\/2026\/05\/image-2-768x347.png 768w, https:\/\/www.visualdomain.ch\/wp-content\/uploads\/2026\/05\/image-2.png 1344w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\tdata-wp-bind--aria-label=\"state.thisImage.triggerButtonAriaLabel\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.thisImage.buttonRight\"\n\t\t\tdata-wp-style--top=\"state.thisImage.buttonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><figcaption class=\"wp-element-caption\">evaluateExamplePolicy<\/figcaption><\/figure>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>var policy = [\n  {\n    path: \"hostname\",\n    type: \"string\",\n    minLength: 3,\n    maxLength: 30,\n    regex: \"^&#91;a-z0-9-&#93;+$\",\n    onMissing: \"fail\",\n    errorMessage: \"Hostname is invalid.\",\n  },\n  {\n    path: \"cpu\",\n    type: \"number\",\n    integerOnly: true,\n    allowedValues: &#91;2, 4, 8&#93;,\n    onMissing: \"fail\",\n    errorMessage: \"CPU must be 2, 4, or 8.\",\n  },\n  {\n    path: \"ports&#91;*&#93;\",\n    type: \"number\",\n    allowedValues: &#91;\"80\", \"443\", \"8443-8445\"&#93;,\n    onMissing: \"fail\",\n    errorMessage: \"port(s) are not allowed: \" + inputDto.ports,\n  }\n];\n\nvar validation =  System.getModule(\"ch.org.security.validation\").dtoValidator(policy, inputDto);\nreturn validation;<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">policy<\/span><span style=\"color: #D4D4D4\"> = [<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">path:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;hostname&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">type:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;string&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">minLength:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">3<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">maxLength:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">30<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">regex:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;^&#91;a-z0-9-&#93;+$&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">onMissing:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;fail&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">errorMessage:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;Hostname is invalid.&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  },<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">path:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;cpu&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">type:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;number&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">integerOnly:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">true<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">allowedValues:<\/span><span style=\"color: #D4D4D4\"> &#91;<\/span><span style=\"color: #B5CEA8\">2<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">4<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">8<\/span><span style=\"color: #D4D4D4\">&#93;,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">onMissing:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;fail&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">errorMessage:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;CPU must be 2, 4, or 8.&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  },<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">path:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;ports&#91;*&#93;&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">type:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;number&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">allowedValues:<\/span><span style=\"color: #D4D4D4\"> &#91;<\/span><span style=\"color: #CE9178\">&quot;80&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&quot;443&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&quot;8443-8445&quot;<\/span><span style=\"color: #D4D4D4\">&#93;,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">onMissing:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;fail&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">errorMessage:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;port(s) are not allowed: &quot;<\/span><span style=\"color: #D4D4D4\"> + <\/span><span style=\"color: #9CDCFE\">inputDto<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">ports<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">];<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">validation<\/span><span style=\"color: #D4D4D4\"> =  <\/span><span style=\"color: #9CDCFE\">System<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">getModule<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;ch.org.security.validation&quot;<\/span><span style=\"color: #D4D4D4\">).<\/span><span style=\"color: #DCDCAA\">dtoValidator<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">policy<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">inputDto<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">validation<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;6ac46c44e9985&quot;}\" data-wp-interactive=\"core\/image\" data-wp-key=\"6ac46c44e9985\" class=\"wp-block-image size-large wp-lightbox-container\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"285\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on--click=\"actions.showLightbox\" data-wp-on--load=\"callbacks.setButtonStyles\" data-wp-on--pointerdown=\"actions.preloadImage\" data-wp-on--pointerenter=\"actions.preloadImageWithDelay\" data-wp-on--pointerleave=\"actions.cancelPreload\" data-wp-on-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/www.visualdomain.ch\/wp-content\/uploads\/2026\/05\/image-1-1024x285.png\" alt=\"\" class=\"wp-image-47\" srcset=\"https:\/\/www.visualdomain.ch\/wp-content\/uploads\/2026\/05\/image-1-1024x285.png 1024w, https:\/\/www.visualdomain.ch\/wp-content\/uploads\/2026\/05\/image-1-300x83.png 300w, https:\/\/www.visualdomain.ch\/wp-content\/uploads\/2026\/05\/image-1-768x214.png 768w, https:\/\/www.visualdomain.ch\/wp-content\/uploads\/2026\/05\/image-1.png 1211w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\tdata-wp-bind--aria-label=\"state.thisImage.triggerButtonAriaLabel\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.thisImage.buttonRight\"\n\t\t\tdata-wp-style--top=\"state.thisImage.buttonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><figcaption class=\"wp-element-caption\">validateInput<\/figcaption><\/figure>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>var _inputDto = JSON.parse(inputDto);\n\nvar result = System.getModule(\"ch.org.day2.validate\").validateExamplePolicy(_inputDto);\n\nreturn result.errors.join(\";\");<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_inputDto<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #4FC1FF\">JSON<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">parse<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">inputDto<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">result<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">System<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">getModule<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;ch.org.day2.validate&quot;<\/span><span style=\"color: #D4D4D4\">).<\/span><span style=\"color: #DCDCAA\">validateExamplePolicy<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">_inputDto<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">result<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">errors<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">join<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;;&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\">This works as long as the validation action always returns a result object with an <code>errors<\/code> array. A slightly more defensive version checks the <code>valid<\/code> flag before returning the validation errors:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>var _inputDto = JSON.parse(inputDto);\n\nvar result = System.getModule(\"ch.org.day2.validate\").validateExamplePolicy(_inputDto);\n\nif(!result.valid) {\n  return result.errors.join(\";\");\n}\n\nreturn \"\";<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_inputDto<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #4FC1FF\">JSON<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">parse<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">inputDto<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">result<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">System<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">getModule<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;ch.org.day2.validate&quot;<\/span><span style=\"color: #D4D4D4\">).<\/span><span style=\"color: #DCDCAA\">validateExamplePolicy<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">_inputDto<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\">(!<\/span><span style=\"color: #9CDCFE\">result<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">valid<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">result<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">errors<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">join<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;;&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;&quot;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;6ac46c44e9fb9&quot;}\" data-wp-interactive=\"core\/image\" data-wp-key=\"6ac46c44e9fb9\" class=\"wp-block-image size-large wp-lightbox-container\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"361\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on--click=\"actions.showLightbox\" data-wp-on--load=\"callbacks.setButtonStyles\" data-wp-on--pointerdown=\"actions.preloadImage\" data-wp-on--pointerenter=\"actions.preloadImageWithDelay\" data-wp-on--pointerleave=\"actions.cancelPreload\" data-wp-on-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/www.visualdomain.ch\/wp-content\/uploads\/2026\/05\/image-3-1024x361.png\" alt=\"\" class=\"wp-image-49\" srcset=\"https:\/\/www.visualdomain.ch\/wp-content\/uploads\/2026\/05\/image-3-1024x361.png 1024w, https:\/\/www.visualdomain.ch\/wp-content\/uploads\/2026\/05\/image-3-300x106.png 300w, https:\/\/www.visualdomain.ch\/wp-content\/uploads\/2026\/05\/image-3-768x270.png 768w, https:\/\/www.visualdomain.ch\/wp-content\/uploads\/2026\/05\/image-3.png 1389w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\tdata-wp-bind--aria-label=\"state.thisImage.triggerButtonAriaLabel\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.thisImage.buttonRight\"\n\t\t\tdata-wp-style--top=\"state.thisImage.buttonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><\/figure>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\">Copy the whole content from <a href=\"https:\/\/github.com\/viscop\/aria-dto-validator\/blob\/main\/validateDto.js\">validateDto.js<\/a> from GitHub<br><a href=\"https:\/\/github.com\/viscop\/aria-dto-validator\">https:\/\/github.com\/viscop\/aria-dto-validator<\/a><br><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Workflow<\/h2>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\">After the action structure has been defined, the next step is the implementation of a simple workflow.<br>The workflow uses the previously created validateInput action and demonstrates how they can be combined into a reusable automation process in Aria Orchestrator.<\/p>\n\n\n\n<p class=\"is-style-default highlight-box ticss-62093dae has-accent-5-background-color has-background has-medium-font-size wp-block-paragraph\" style=\"border-top-left-radius:5px;border-top-right-radius:5px;border-bottom-left-radius:5px;border-bottom-right-radius:5px;padding-top:var(--wp--preset--spacing--20);padding-right:var(--wp--preset--spacing--30);padding-bottom:var(--wp--preset--spacing--20);padding-left:var(--wp--preset--spacing--30)\">Whenever possible, I prefer to use a single workflow input that contains a JSON payload.This payload acts as a DTO, a Data Transfer Object.Instead of passing many separate workflow inputs, the workflow receives one structured object:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>{\n  \"hostname\": \"test123\",\n  \"cpu\": 4,\n  \"ports\": &#91;\"80\", \"443\"&#93;\n}<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D4D4D4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #9CDCFE\">&quot;hostname&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;test123&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #9CDCFE\">&quot;cpu&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #B5CEA8\">4<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #9CDCFE\">&quot;ports&quot;<\/span><span style=\"color: #D4D4D4\">: &#91;<\/span><span style=\"color: #CE9178\">&quot;80&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&quot;443&quot;<\/span><span style=\"color: #D4D4D4\">&#93;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\">This makes handling the input much easier.<\/p>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\">The downside is that the JSON properties must be documented properly, so that other engineers understand which fields are expected. But in practice, this documentation is required anyway.<\/p>\n\n\n\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;6ac46c44ea798&quot;}\" data-wp-interactive=\"core\/image\" data-wp-key=\"6ac46c44ea798\" class=\"wp-block-image size-large wp-lightbox-container\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"261\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on--click=\"actions.showLightbox\" data-wp-on--load=\"callbacks.setButtonStyles\" data-wp-on--pointerdown=\"actions.preloadImage\" data-wp-on--pointerenter=\"actions.preloadImageWithDelay\" data-wp-on--pointerleave=\"actions.cancelPreload\" data-wp-on-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/www.visualdomain.ch\/wp-content\/uploads\/2026\/05\/image-4-1024x261.png\" alt=\"\" class=\"wp-image-50\" srcset=\"https:\/\/www.visualdomain.ch\/wp-content\/uploads\/2026\/05\/image-4-1024x261.png 1024w, https:\/\/www.visualdomain.ch\/wp-content\/uploads\/2026\/05\/image-4-300x77.png 300w, https:\/\/www.visualdomain.ch\/wp-content\/uploads\/2026\/05\/image-4-768x196.png 768w, https:\/\/www.visualdomain.ch\/wp-content\/uploads\/2026\/05\/image-4.png 1098w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\tdata-wp-bind--aria-label=\"state.thisImage.triggerButtonAriaLabel\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.thisImage.buttonRight\"\n\t\t\tdata-wp-style--top=\"state.thisImage.buttonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><\/figure>\n\n\n\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;6ac46c44eac8e&quot;}\" data-wp-interactive=\"core\/image\" data-wp-key=\"6ac46c44eac8e\" class=\"wp-block-image size-large has-custom-border is-style-default wp-lightbox-container\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"441\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on--click=\"actions.showLightbox\" data-wp-on--load=\"callbacks.setButtonStyles\" data-wp-on--pointerdown=\"actions.preloadImage\" data-wp-on--pointerenter=\"actions.preloadImageWithDelay\" data-wp-on--pointerleave=\"actions.cancelPreload\" data-wp-on-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/www.visualdomain.ch\/wp-content\/uploads\/2026\/05\/image-5-1024x441.png\" alt=\"\" class=\"wp-image-51\" style=\"border-top-left-radius:0px;border-top-right-radius:0px;border-bottom-left-radius:0px;border-bottom-right-radius:0px\" srcset=\"https:\/\/www.visualdomain.ch\/wp-content\/uploads\/2026\/05\/image-5-1024x441.png 1024w, https:\/\/www.visualdomain.ch\/wp-content\/uploads\/2026\/05\/image-5-300x129.png 300w, https:\/\/www.visualdomain.ch\/wp-content\/uploads\/2026\/05\/image-5-768x331.png 768w, https:\/\/www.visualdomain.ch\/wp-content\/uploads\/2026\/05\/image-5.png 1247w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\tdata-wp-bind--aria-label=\"state.thisImage.triggerButtonAriaLabel\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.thisImage.buttonRight\"\n\t\t\tdata-wp-style--top=\"state.thisImage.buttonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><\/figure>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>var validationErrors = System.getModule(\"ch.org.day2.validate\").validateInput(inputDto);\n\nif (validationErrors &amp;&amp; validationErrors.length > 0) {\n    throw validationErrors;\n}<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">validationErrors<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">System<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">getModule<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;ch.org.day2.validate&quot;<\/span><span style=\"color: #D4D4D4\">).<\/span><span style=\"color: #DCDCAA\">validateInput<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">inputDto<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">validationErrors<\/span><span style=\"color: #D4D4D4\"> &amp;&amp; <\/span><span style=\"color: #9CDCFE\">validationErrors<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">length<\/span><span style=\"color: #D4D4D4\"> &gt; <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #C586C0\">throw<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">validationErrors<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"is-style-default highlight-box ticss-62093dae has-accent-5-background-color has-background has-medium-font-size wp-block-paragraph\" style=\"border-top-left-radius:5px;border-top-right-radius:5px;border-bottom-left-radius:5px;border-bottom-right-radius:5px;padding-top:var(--wp--preset--spacing--20);padding-right:var(--wp--preset--spacing--30);padding-bottom:var(--wp--preset--spacing--20);padding-left:var(--wp--preset--spacing--30)\"><strong>Why should validation also be performed inside the workflow?<\/strong><br><br>The configured input validation is automatically executed for catalog items, Day 2 actions, and resource actions. This ensures that submitted form data is validated before the workflow is invoked through the regular request process.<br><br>However, this validation is tied to the request layer. If the workflow is executed directly, for example through the REST API, the configured input validation is not executed. For this reason, business-critical validation should also be implemented inside the workflow.<br><br>Workflow-level validation adds an additional layer of protection and ensures that critical processes are validated independently of how the workflow was started.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><br>Custom Form<\/h2>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\">In this example, the form contains three visible input fields and one DTO field that is passed to the workflow.<\/p>\n\n\n\n<figure class=\"wp-block-table has-medium-font-size\"><table class=\"has-fixed-layout\" style=\"border-style:none;border-width:0px\"><thead><tr><th class=\"has-text-align-left\" data-align=\"left\">Field<\/th><th class=\"has-text-align-left\" data-align=\"left\">Display Type<\/th><th class=\"has-text-align-left\" data-align=\"left\">Purpose<\/th><\/tr><\/thead><tbody><tr><td class=\"has-text-align-left\" data-align=\"left\">hostname<\/td><td class=\"has-text-align-left\" data-align=\"left\">Text Field<\/td><td class=\"has-text-align-left\" data-align=\"left\">String representation of the host name<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">cpu<\/td><td class=\"has-text-align-left\" data-align=\"left\">Integer<\/td><td class=\"has-text-align-left\" data-align=\"left\">Number of CPUs<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">ports<\/td><td class=\"has-text-align-left\" data-align=\"left\">Array Input, String<\/td><td class=\"has-text-align-left\" data-align=\"left\">List of TCP ports<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">inputDto<\/td><td class=\"has-text-align-left\" data-align=\"left\">Text or hidden field<\/td><td class=\"has-text-align-left\" data-align=\"left\">JSON representation of the DTO passed to the workflow<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;6ac46c44eb386&quot;}\" data-wp-interactive=\"core\/image\" data-wp-key=\"6ac46c44eb386\" class=\"wp-block-image size-full wp-lightbox-container\"><img loading=\"lazy\" decoding=\"async\" width=\"878\" height=\"553\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on--click=\"actions.showLightbox\" data-wp-on--load=\"callbacks.setButtonStyles\" data-wp-on--pointerdown=\"actions.preloadImage\" data-wp-on--pointerenter=\"actions.preloadImageWithDelay\" data-wp-on--pointerleave=\"actions.cancelPreload\" data-wp-on-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/www.visualdomain.ch\/wp-content\/uploads\/2026\/05\/image-6.png\" alt=\"\" class=\"wp-image-56\" srcset=\"https:\/\/www.visualdomain.ch\/wp-content\/uploads\/2026\/05\/image-6.png 878w, https:\/\/www.visualdomain.ch\/wp-content\/uploads\/2026\/05\/image-6-300x189.png 300w, https:\/\/www.visualdomain.ch\/wp-content\/uploads\/2026\/05\/image-6-768x484.png 768w\" sizes=\"auto, (max-width: 878px) 100vw, 878px\" \/><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\tdata-wp-bind--aria-label=\"state.thisImage.triggerButtonAriaLabel\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.thisImage.buttonRight\"\n\t\t\tdata-wp-style--top=\"state.thisImage.buttonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><\/figure>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\">The <code>inputDto<\/code> workflow input requires a JSON string, which is generated by the <code>buildInputDto<\/code> action.<br>The custom form action builds the DTO from the visible form fields.<\/p>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\"><\/p>\n\n\n\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;6ac46c44eb952&quot;}\" data-wp-interactive=\"core\/image\" data-wp-key=\"6ac46c44eb952\" class=\"wp-block-image size-large is-style-default wp-lightbox-container\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"470\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on--click=\"actions.showLightbox\" data-wp-on--load=\"callbacks.setButtonStyles\" data-wp-on--pointerdown=\"actions.preloadImage\" data-wp-on--pointerenter=\"actions.preloadImageWithDelay\" data-wp-on--pointerleave=\"actions.cancelPreload\" data-wp-on-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/www.visualdomain.ch\/wp-content\/uploads\/2026\/05\/image-7-1024x470.png\" alt=\"\" class=\"wp-image-57\" srcset=\"https:\/\/www.visualdomain.ch\/wp-content\/uploads\/2026\/05\/image-7-1024x470.png 1024w, https:\/\/www.visualdomain.ch\/wp-content\/uploads\/2026\/05\/image-7-300x138.png 300w, https:\/\/www.visualdomain.ch\/wp-content\/uploads\/2026\/05\/image-7-768x353.png 768w, https:\/\/www.visualdomain.ch\/wp-content\/uploads\/2026\/05\/image-7.png 1281w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\tdata-wp-bind--aria-label=\"state.thisImage.triggerButtonAriaLabel\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.thisImage.buttonRight\"\n\t\t\tdata-wp-style--top=\"state.thisImage.buttonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><\/figure>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\">To enable UI validation, a validation rule must be configured.<br>The rule uses the previously created <code>validateInput<\/code> action.<\/p>\n\n\n\n<p class=\"is-style-default highlight-box ticss-62093dae has-accent-5-background-color has-background has-medium-font-size wp-block-paragraph\" style=\"border-top-left-radius:5px;border-top-right-radius:5px;border-bottom-left-radius:5px;border-bottom-right-radius:5px;padding-top:var(--wp--preset--spacing--20);padding-right:var(--wp--preset--spacing--30);padding-bottom:var(--wp--preset--spacing--20);padding-left:var(--wp--preset--spacing--30)\">The <code>validateInput<\/code> action was intentionally designed to return validation errors as a single string. An empty string means that the validation passed successfully. A non-empty string indicates that the validation failed, and the returned value contains the error message(s) displayed to the user.<\/p>\n\n\n\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;6ac46c44ebf77&quot;}\" data-wp-interactive=\"core\/image\" data-wp-key=\"6ac46c44ebf77\" class=\"wp-block-image size-large wp-lightbox-container\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"448\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on--click=\"actions.showLightbox\" data-wp-on--load=\"callbacks.setButtonStyles\" data-wp-on--pointerdown=\"actions.preloadImage\" data-wp-on--pointerenter=\"actions.preloadImageWithDelay\" data-wp-on--pointerleave=\"actions.cancelPreload\" data-wp-on-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/www.visualdomain.ch\/wp-content\/uploads\/2026\/05\/image-9-1024x448.png\" alt=\"\" class=\"wp-image-59\" srcset=\"https:\/\/www.visualdomain.ch\/wp-content\/uploads\/2026\/05\/image-9-1024x448.png 1024w, https:\/\/www.visualdomain.ch\/wp-content\/uploads\/2026\/05\/image-9-300x131.png 300w, https:\/\/www.visualdomain.ch\/wp-content\/uploads\/2026\/05\/image-9-768x336.png 768w, https:\/\/www.visualdomain.ch\/wp-content\/uploads\/2026\/05\/image-9.png 1233w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\tdata-wp-bind--aria-label=\"state.thisImage.triggerButtonAriaLabel\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.thisImage.buttonRight\"\n\t\t\tdata-wp-style--top=\"state.thisImage.buttonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><\/figure>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\">All components are now integrated and ready to use. Feel free to experiment with the implementation and adapt it to your own workflows.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span id=\"bppb-heading-anchor-10\"><\/span>AI Disclosure<\/h2>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\">The concept, architecture, and functional design of the input validation approach described in this article were conceived by the author. The implementation and project-specific automated tests were generated using AI based on these requirements and design decisions.<\/p>\n\n\n\n<p class=\"has-medium-font-size wp-block-paragraph\">AI was also used to assist with writing and editing this article. The final content was reviewed by the author.<\/p>\n\n\n\n<div class=\"wp-block-comments\"><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction Input validation in VMware Aria Automation and VMware Aria Orchestrator often starts simple. A virtual disk must be between 10 and 2000 GB.A CPU value must be one of a few allowed options.A list of TCP ports must stay within an approved range. At first, this is easy to solve with imperative validation code. [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":5,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":25,"footnotes":""},"categories":[7,6,8,9],"tags":[],"class_list":["post-112","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-aria-automation","category-aria-orchestrator","category-vcf-automation","category-vcf-orchestrator"],"_links":{"self":[{"href":"https:\/\/www.visualdomain.ch\/index.php?rest_route=\/wp\/v2\/posts\/112","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.visualdomain.ch\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.visualdomain.ch\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.visualdomain.ch\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.visualdomain.ch\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=112"}],"version-history":[{"count":25,"href":"https:\/\/www.visualdomain.ch\/index.php?rest_route=\/wp\/v2\/posts\/112\/revisions"}],"predecessor-version":[{"id":258,"href":"https:\/\/www.visualdomain.ch\/index.php?rest_route=\/wp\/v2\/posts\/112\/revisions\/258"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.visualdomain.ch\/index.php?rest_route=\/wp\/v2\/media\/5"}],"wp:attachment":[{"href":"https:\/\/www.visualdomain.ch\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=112"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.visualdomain.ch\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=112"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.visualdomain.ch\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=112"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}