This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch feature/CAMEL-23530-dataweave-component
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 908a6dd8cfe46b02fe10d363abb2f85e5d384911
Author: Claus Ibsen <[email protected]>
AuthorDate: Wed Aug 5 16:19:10 2026 +0200

    CAMEL-23530: Move DataWeave parser to camel-dataweave component for reuse
    
    Co-Authored-By: Claude Opus 4.6 <[email protected]>
    Signed-off-by: Claus Ibsen <[email protected]>
---
 bom/camel-bom/pom.xml                              |  5 ++
 catalog/camel-allcomponents/pom.xml                |  5 ++
 .../org/apache/camel/catalog/others.properties     |  1 +
 .../org/apache/camel/catalog/others/dataweave.json | 15 ++++
 components/camel-dataweave/pom.xml                 | 54 +++++++++++++++
 .../services/org/apache/camel/other.properties     |  7 ++
 .../src/generated/resources/dataweave.json         | 15 ++++
 .../camel/component/dataweave}/DataWeaveAst.java   |  2 +-
 .../component/dataweave}/DataWeaveConverter.java   | 20 +++---
 .../camel/component/dataweave}/DataWeaveLexer.java |  2 +-
 .../component/dataweave}/DataWeaveParser.java      | 16 ++---
 .../dataweave}/DataWeaveConverterTest.java         | 45 ++++++------
 .../component/dataweave}/DataWeaveLexerTest.java   | 21 +-----
 .../component/dataweave}/DataWeaveParserTest.java  | 80 +++++++++-------------
 .../test/resources/dataweave/collection-map.dwl    |  0
 .../src/test/resources/dataweave/event-message.dwl |  0
 .../src/test/resources/dataweave/null-handling.dwl |  0
 .../src/test/resources/dataweave/simple-rename.dwl |  0
 .../src/test/resources/dataweave/string-ops.dwl    |  0
 .../src/test/resources/dataweave/type-coercion.dwl |  0
 components/pom.xml                                 |  1 +
 .../modules/others/examples/json/dataweave.json    |  1 +
 dsl/camel-jbang/camel-jbang-core/pom.xml           |  4 ++
 .../jbang/core/commands/TransformDataWeave.java    |  2 +-
 parent/pom.xml                                     |  5 ++
 25 files changed, 190 insertions(+), 111 deletions(-)

diff --git a/bom/camel-bom/pom.xml b/bom/camel-bom/pom.xml
index ea5383026c76..f6f06b4f00b6 100644
--- a/bom/camel-bom/pom.xml
+++ b/bom/camel-bom/pom.xml
@@ -707,6 +707,11 @@
         <artifactId>camel-datasonnet</artifactId>
         <version>4.22.0-SNAPSHOT</version>
       </dependency>
+      <dependency>
+        <groupId>org.apache.camel</groupId>
+        <artifactId>camel-dataweave</artifactId>
+        <version>4.22.0-SNAPSHOT</version>
+      </dependency>
       <dependency>
         <groupId>org.apache.camel</groupId>
         <artifactId>camel-debezium-common</artifactId>
diff --git a/catalog/camel-allcomponents/pom.xml 
b/catalog/camel-allcomponents/pom.xml
index 9ff95f7750ff..0afdc8f168ad 100644
--- a/catalog/camel-allcomponents/pom.xml
+++ b/catalog/camel-allcomponents/pom.xml
@@ -597,6 +597,11 @@
             <artifactId>camel-datasonnet</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-dataweave</artifactId>
+            <version>${project.version}</version>
+        </dependency>
         <dependency>
             <groupId>org.apache.camel</groupId>
             <artifactId>camel-debezium-common</artifactId>
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/others.properties
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/others.properties
index e1c80fb21928..20197d007d61 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/others.properties
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/others.properties
@@ -7,6 +7,7 @@ cluster
 componentdsl
 console
 csimple-joor
+dataweave
 debug
 diagram
 dsl-modeline
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/others/dataweave.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/others/dataweave.json
new file mode 100644
index 000000000000..c41beea0ddf9
--- /dev/null
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/others/dataweave.json
@@ -0,0 +1,15 @@
+{
+  "other": {
+    "kind": "other",
+    "name": "dataweave",
+    "title": "Dataweave",
+    "description": "Camel DataWeave support",
+    "deprecated": false,
+    "firstVersion": "4.22.0",
+    "label": "transformation",
+    "supportLevel": "Preview",
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-dataweave",
+    "version": "4.22.0-SNAPSHOT"
+  }
+}
diff --git a/components/camel-dataweave/pom.xml 
b/components/camel-dataweave/pom.xml
new file mode 100644
index 000000000000..492acf2f43ce
--- /dev/null
+++ b/components/camel-dataweave/pom.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.camel</groupId>
+        <artifactId>components</artifactId>
+        <version>4.22.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>camel-dataweave</artifactId>
+    <packaging>jar</packaging>
+
+    <name>Camel :: DataWeave</name>
+    <description>Camel DataWeave support</description>
+
+    <properties>
+        <firstVersion>4.22.0</firstVersion>
+        <label>transformation</label>
+    </properties>
+
+    <dependencies>
+        <!-- test dependencies -->
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.assertj</groupId>
+            <artifactId>assertj-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+</project>
diff --git 
a/components/camel-dataweave/src/generated/resources/META-INF/services/org/apache/camel/other.properties
 
b/components/camel-dataweave/src/generated/resources/META-INF/services/org/apache/camel/other.properties
new file mode 100644
index 000000000000..40bc48ca1d26
--- /dev/null
+++ 
b/components/camel-dataweave/src/generated/resources/META-INF/services/org/apache/camel/other.properties
@@ -0,0 +1,7 @@
+# Generated by camel build tools - do NOT edit this file!
+name=dataweave
+groupId=org.apache.camel
+artifactId=camel-dataweave
+version=4.22.0-SNAPSHOT
+projectName=Camel :: DataWeave
+projectDescription=Camel DataWeave support
diff --git a/components/camel-dataweave/src/generated/resources/dataweave.json 
b/components/camel-dataweave/src/generated/resources/dataweave.json
new file mode 100644
index 000000000000..c41beea0ddf9
--- /dev/null
+++ b/components/camel-dataweave/src/generated/resources/dataweave.json
@@ -0,0 +1,15 @@
+{
+  "other": {
+    "kind": "other",
+    "name": "dataweave",
+    "title": "Dataweave",
+    "description": "Camel DataWeave support",
+    "deprecated": false,
+    "firstVersion": "4.22.0",
+    "label": "transformation",
+    "supportLevel": "Preview",
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-dataweave",
+    "version": "4.22.0-SNAPSHOT"
+  }
+}
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/transform/DataWeaveAst.java
 
b/components/camel-dataweave/src/main/java/org/apache/camel/component/dataweave/DataWeaveAst.java
similarity index 98%
rename from 
dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/transform/DataWeaveAst.java
rename to 
components/camel-dataweave/src/main/java/org/apache/camel/component/dataweave/DataWeaveAst.java
index 4b75a0569aff..f1ef34b9b40b 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/transform/DataWeaveAst.java
+++ 
b/components/camel-dataweave/src/main/java/org/apache/camel/component/dataweave/DataWeaveAst.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.dsl.jbang.core.commands.transform;
+package org.apache.camel.component.dataweave;
 
 import java.util.List;
 
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/transform/DataWeaveConverter.java
 
b/components/camel-dataweave/src/main/java/org/apache/camel/component/dataweave/DataWeaveConverter.java
similarity index 96%
rename from 
dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/transform/DataWeaveConverter.java
rename to 
components/camel-dataweave/src/main/java/org/apache/camel/component/dataweave/DataWeaveConverter.java
index 3842f29b2c5e..6bc12820c8ea 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/transform/DataWeaveConverter.java
+++ 
b/components/camel-dataweave/src/main/java/org/apache/camel/component/dataweave/DataWeaveConverter.java
@@ -14,13 +14,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.dsl.jbang.core.commands.transform;
+package org.apache.camel.component.dataweave;
 
 import java.util.ArrayList;
 import java.util.List;
 
-import org.apache.camel.dsl.jbang.core.commands.transform.DataWeaveAst.*;
-import org.apache.camel.dsl.jbang.core.commands.transform.DataWeaveLexer.Token;
+import org.apache.camel.component.dataweave.DataWeaveAst.*;
+import org.apache.camel.component.dataweave.DataWeaveLexer.Token;
 
 /**
  * Converts DataWeave 2.0 scripts to DataSonnet. Parses the DataWeave input, 
walks the AST, and emits equivalent
@@ -84,7 +84,7 @@ public class DataWeaveConverter {
         return emitNode(ast);
     }
 
-    // ── Emission ──
+    // -- Emission --
 
     private String emit(DataWeaveAst node) {
         if (node instanceof Script script) {
@@ -352,7 +352,7 @@ public class DataWeaveConverter {
             case "Boolean" -> "cml.toBoolean(" + expr + ")";
             default -> {
                 todoCount++;
-                yield expr + (includeComments ? " // TODO: manual conversion 
needed — as " + tc.type() : "");
+                yield expr + (includeComments ? " // TODO: manual conversion 
needed -- as " + tc.type() : "");
             }
         };
     }
@@ -410,9 +410,9 @@ public class DataWeaveConverter {
                 yield "c.max(" + argStr + ")";
             }
             case "read" -> "std.parseJson(" + argStr + ")"
-                           + (includeComments ? " // NOTE: assumes JSON input 
— DW read() supports multiple formats" : "");
+                           + (includeComments ? " // NOTE: assumes JSON input 
-- DW read() supports multiple formats" : "");
             case "write" -> "std.manifestJsonEx(" + argStr + ", \"  \")"
-                            + (includeComments ? " // NOTE: outputs JSON — DW 
write() supports multiple formats" : "");
+                            + (includeComments ? " // NOTE: outputs JSON -- DW 
write() supports multiple formats" : "");
             default -> fc.name() + "(" + argStr + ")";
         };
     }
@@ -436,7 +436,7 @@ public class DataWeaveConverter {
             List<String> paramNames = lambdaParamNames(lam);
             String body = emitNode(lam.body());
             if (paramNames.size() == 2) {
-                // DW: map ((item, index) -> body) — DS: 
std.mapWithIndex(function(index, item) body, collection)
+                // DW: map ((item, index) -> body) -- DS: 
std.mapWithIndex(function(index, item) body, collection)
                 // Parameter order is swapped: DW is (item, index), DS is 
(index, item)
                 return "std.mapWithIndex(function(" + paramNames.get(1) + ", " 
+ paramNames.get(0)
                        + ") " + body + ", " + collection + ")";
@@ -498,7 +498,7 @@ public class DataWeaveConverter {
         if (dbe.lambda() instanceof Lambda lam) {
             List<String> paramNames = lambdaParamNames(lam);
             String body = emitNode(lam.body());
-            // distinctBy keeps first occurrence per key — use distinctBy 
helper
+            // distinctBy keeps first occurrence per key -- use distinctBy 
helper
             return "c.distinctBy(" + collection + ", function(" + 
paramNames.get(0) + ") " + body + ")";
         }
         return "c.distinct(" + collection + ")";
@@ -593,7 +593,7 @@ public class DataWeaveConverter {
         todoCount++;
         convertedCount--;
         return includeComments
-                ? "// TODO: manual conversion needed — " + u.reason() + ": " + 
u.originalText() + "\nnull"
+                ? "// TODO: manual conversion needed -- " + u.reason() + ": " 
+ u.originalText() + "\nnull"
                 : "null";
     }
 
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/transform/DataWeaveLexer.java
 
b/components/camel-dataweave/src/main/java/org/apache/camel/component/dataweave/DataWeaveLexer.java
similarity index 99%
rename from 
dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/transform/DataWeaveLexer.java
rename to 
components/camel-dataweave/src/main/java/org/apache/camel/component/dataweave/DataWeaveLexer.java
index 1d74d45d7382..703424acaeb6 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/transform/DataWeaveLexer.java
+++ 
b/components/camel-dataweave/src/main/java/org/apache/camel/component/dataweave/DataWeaveLexer.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.dsl.jbang.core.commands.transform;
+package org.apache.camel.component.dataweave;
 
 import java.util.ArrayList;
 import java.util.List;
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/transform/DataWeaveParser.java
 
b/components/camel-dataweave/src/main/java/org/apache/camel/component/dataweave/DataWeaveParser.java
similarity index 98%
rename from 
dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/transform/DataWeaveParser.java
rename to 
components/camel-dataweave/src/main/java/org/apache/camel/component/dataweave/DataWeaveParser.java
index 8c2f62c29dfb..e91187d23f17 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/transform/DataWeaveParser.java
+++ 
b/components/camel-dataweave/src/main/java/org/apache/camel/component/dataweave/DataWeaveParser.java
@@ -14,13 +14,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.dsl.jbang.core.commands.transform;
+package org.apache.camel.component.dataweave;
 
 import java.util.ArrayList;
 import java.util.List;
 
-import org.apache.camel.dsl.jbang.core.commands.transform.DataWeaveLexer.Token;
-import 
org.apache.camel.dsl.jbang.core.commands.transform.DataWeaveLexer.TokenType;
+import org.apache.camel.component.dataweave.DataWeaveLexer.Token;
+import org.apache.camel.component.dataweave.DataWeaveLexer.TokenType;
 
 /**
  * Recursive descent parser for DataWeave 2.0 scripts producing {@link 
DataWeaveAst} nodes.
@@ -45,7 +45,7 @@ public class DataWeaveParser {
         return parseExpression();
     }
 
-    // ── Header parsing ──
+    // -- Header parsing --
 
     private DataWeaveAst.Header parseHeader() {
         String version = "2.0";
@@ -57,7 +57,7 @@ public class DataWeaveParser {
                 || checkIdentifier("output") || checkIdentifier("input");
 
         if (!hasHeader) {
-            // No header section — skip directly to body
+            // No header section -- skip directly to body
             return new DataWeaveAst.Header(version, null, inputs);
         }
 
@@ -118,7 +118,7 @@ public class DataWeaveParser {
         return sb.toString();
     }
 
-    // ── Expression parsing (precedence climbing) ──
+    // -- Expression parsing (precedence climbing) --
 
     private DataWeaveAst parseExpression() {
         // Handle var/fun declarations at expression level
@@ -442,7 +442,7 @@ public class DataWeaveParser {
                 expr = new DataWeaveAst.ReplaceExpr(expr, target, replacement);
             } else if (checkIdentifier("match")) {
                 advance(); // match
-                // Capture the match block as unsupported — skip braces
+                // Capture the match block as unsupported -- skip braces
                 StringBuilder matchText = new StringBuilder("match ");
                 if (check(TokenType.LBRACE)) {
                     int depth = 1;
@@ -717,7 +717,7 @@ public class DataWeaveParser {
         return new DataWeaveAst.ArrayLit(elements);
     }
 
-    // ── Token helpers ──
+    // -- Token helpers --
 
     private Token current() {
         return pos < tokens.size() ? tokens.get(pos) : 
tokens.get(tokens.size() - 1);
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/transform/DataWeaveConverterTest.java
 
b/components/camel-dataweave/src/test/java/org/apache/camel/component/dataweave/DataWeaveConverterTest.java
similarity index 93%
rename from 
dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/transform/DataWeaveConverterTest.java
rename to 
components/camel-dataweave/src/test/java/org/apache/camel/component/dataweave/DataWeaveConverterTest.java
index c2424bd1e66a..e435af0e483f 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/transform/DataWeaveConverterTest.java
+++ 
b/components/camel-dataweave/src/test/java/org/apache/camel/component/dataweave/DataWeaveConverterTest.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.dsl.jbang.core.commands.transform;
+package org.apache.camel.component.dataweave;
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -34,7 +34,7 @@ class DataWeaveConverterTest {
         converter = new DataWeaveConverter();
     }
 
-    // ── Header conversion ──
+    // -- Header conversion --
 
     @Test
     void testHeaderConversion() {
@@ -51,7 +51,7 @@ class DataWeaveConverterTest {
         assertTrue(result.contains("*/"));
     }
 
-    // ── Field access ──
+    // -- Field access --
 
     @Test
     void testPayloadToBody() {
@@ -83,7 +83,7 @@ class DataWeaveConverterTest {
         assertEquals("cml.header('page')", result);
     }
 
-    // ── Operators ──
+    // -- Operators --
 
     @Test
     void testStringConcat() {
@@ -109,7 +109,7 @@ class DataWeaveConverterTest {
         assertEquals("body.active && body.verified", result);
     }
 
-    // ── Default operator ──
+    // -- Default operator --
 
     @Test
     void testDefault() {
@@ -117,7 +117,7 @@ class DataWeaveConverterTest {
         assertEquals("cml.defaultVal(body.currency, \"USD\")", result);
     }
 
-    // ── Type coercion ──
+    // -- Type coercion --
 
     @Test
     void testAsNumber() {
@@ -143,7 +143,7 @@ class DataWeaveConverterTest {
         assertEquals("cml.toBoolean(body.active)", result);
     }
 
-    // ── Built-in functions ──
+    // -- Built-in functions --
 
     @Test
     void testSizeOf() {
@@ -194,7 +194,7 @@ class DataWeaveConverterTest {
         assertTrue(converter.needsCamelLib());
     }
 
-    // ── String operations ──
+    // -- String operations --
 
     @Test
     void testContains() {
@@ -221,7 +221,7 @@ class DataWeaveConverterTest {
         assertEquals("std.strReplace(body.text, \"old\", \"new\")", result);
     }
 
-    // ── Collection operations ──
+    // -- Collection operations --
 
     @Test
     void testMap() {
@@ -250,10 +250,8 @@ class DataWeaveConverterTest {
 
     @Test
     void testReduceParamSwap() {
-        // Verify that acc and item params are swapped for std.foldl
         String result = converter.convertExpression(
                 "payload.items reduce ((item, acc = 0) -> acc + item.price)");
-        // In std.foldl, it should be function(acc, item) not function(item, 
acc)
         assertTrue(result.contains("function(acc, item)"));
     }
 
@@ -265,7 +263,7 @@ class DataWeaveConverterTest {
         assertTrue(result.contains("item.tags"));
     }
 
-    // ── If/else ──
+    // -- If/else --
 
     @Test
     void testIfElse() {
@@ -274,7 +272,7 @@ class DataWeaveConverterTest {
         assertEquals("if body.age >= 18 then \"adult\" else \"minor\"", 
result);
     }
 
-    // ── Object and array literals ──
+    // -- Object and array literals --
 
     @Test
     void testObjectLiteral() {
@@ -289,7 +287,7 @@ class DataWeaveConverterTest {
         assertEquals("[1, 2, 3]", result);
     }
 
-    // ── Full script tests ──
+    // -- Full script tests --
 
     @Test
     void testSimpleRenameScript() throws IOException {
@@ -382,7 +380,7 @@ class DataWeaveConverterTest {
         assertTrue(result.contains("name: body.name"));
     }
 
-    // ── startsWith / endsWith ──
+    // -- startsWith / endsWith --
 
     @Test
     void testStartsWith() {
@@ -398,7 +396,7 @@ class DataWeaveConverterTest {
         assertTrue(converter.needsCamelLib());
     }
 
-    // ── Math functions ──
+    // -- Math functions --
 
     @Test
     void testAbs() {
@@ -427,17 +425,16 @@ class DataWeaveConverterTest {
         assertTrue(converter.needsCamelLib());
     }
 
-    // ── mapWithIndex parameter order ──
+    // -- mapWithIndex parameter order --
 
     @Test
     void testMapWithIndex() {
         String result = converter.convertExpression(
                 "payload.items map ((item, idx) -> { index: idx, name: 
item.name })");
-        // DataSonnet std.mapWithIndex uses function(index, item), so params 
must be swapped
         assertTrue(result.contains("std.mapWithIndex(function(idx, item)"));
     }
 
-    // ── distinctBy ──
+    // -- distinctBy --
 
     @Test
     void testDistinctBy() {
@@ -448,7 +445,7 @@ class DataWeaveConverterTest {
         assertTrue(converter.needsCamelLib());
     }
 
-    // ── Lambda shorthand ──
+    // -- Lambda shorthand --
 
     @Test
     void testLambdaShorthand() {
@@ -456,7 +453,7 @@ class DataWeaveConverterTest {
         assertTrue(result.contains("function(x) x.name"));
     }
 
-    // ── match expression ──
+    // -- match expression --
 
     @Test
     void testMatchExpressionUnsupported() {
@@ -466,7 +463,7 @@ class DataWeaveConverterTest {
         assertTrue(converter.getTodoCount() > 0);
     }
 
-    // ── Multi-value selector ──
+    // -- Multi-value selector --
 
     @Test
     void testMultiValueSelector() {
@@ -475,7 +472,7 @@ class DataWeaveConverterTest {
         assertEquals(0, converter.getTodoCount());
     }
 
-    // ── Escape handling ──
+    // -- Escape handling --
 
     @Test
     void testStringEscapesPreserved() {
@@ -483,7 +480,7 @@ class DataWeaveConverterTest {
         assertTrue(result.contains("\"\\n\""), "Newline escape should be 
preserved, got: " + result);
     }
 
-    // ── Helpers ──
+    // -- Helpers --
 
     private String loadResource(String path) throws IOException {
         try (InputStream is = 
getClass().getClassLoader().getResourceAsStream(path)) {
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/transform/DataWeaveLexerTest.java
 
b/components/camel-dataweave/src/test/java/org/apache/camel/component/dataweave/DataWeaveLexerTest.java
similarity index 79%
rename from 
dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/transform/DataWeaveLexerTest.java
rename to 
components/camel-dataweave/src/test/java/org/apache/camel/component/dataweave/DataWeaveLexerTest.java
index 9395ac07424c..76a66320039a 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/transform/DataWeaveLexerTest.java
+++ 
b/components/camel-dataweave/src/test/java/org/apache/camel/component/dataweave/DataWeaveLexerTest.java
@@ -14,23 +14,16 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.dsl.jbang.core.commands.transform;
+package org.apache.camel.component.dataweave;
 
 import java.util.List;
 
-import org.apache.camel.dsl.jbang.core.commands.transform.DataWeaveLexer.Token;
-import 
org.apache.camel.dsl.jbang.core.commands.transform.DataWeaveLexer.TokenType;
+import org.apache.camel.component.dataweave.DataWeaveLexer.Token;
+import org.apache.camel.component.dataweave.DataWeaveLexer.TokenType;
 import org.junit.jupiter.api.Test;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 
-/**
- * Unit tests for {@link DataWeaveLexer}.
- *
- * These assert the concrete token stream (types, values and positions) for 
representative inputs, focusing on the
- * tricky, ambiguous cases where a tokenizer typically goes wrong: 
multi-character operators, negative numbers vs the
- * minus operator, the {@code ---} header separator, and comment skipping.
- */
 class DataWeaveLexerTest {
 
     private static List<Token> tokenize(String input) {
@@ -50,7 +43,6 @@ class DataWeaveLexerTest {
 
     @Test
     void shouldClassifyKeywordsAndIdentifiers() {
-        // true/false -> BOOLEAN, null -> NULL_LIT, and/or/not -> logical ops, 
everything else -> IDENTIFIER
         assertEquals(
                 List.of(TokenType.BOOLEAN, TokenType.BOOLEAN, 
TokenType.NULL_LIT,
                         TokenType.AND, TokenType.OR, TokenType.NOT,
@@ -65,7 +57,6 @@ class DataWeaveLexerTest {
         assertEquals("hello", tokens.get(0).value());
         assertEquals(TokenType.STRING, tokens.get(1).type());
         assertEquals("world", tokens.get(1).value());
-        // the escaped quote is preserved verbatim inside the string value
         assertEquals("a\\\"b", tokens.get(2).value());
     }
 
@@ -78,7 +69,6 @@ class DataWeaveLexerTest {
 
     @Test
     void shouldTreatLeadingMinusAsNegativeNumberWhenNotAfterValue() {
-        // at the start of input the minus binds to the number
         List<Token> tokens = tokenize("-5");
         assertEquals(TokenType.NUMBER, tokens.get(0).type());
         assertEquals("-5", tokens.get(0).value());
@@ -86,7 +76,6 @@ class DataWeaveLexerTest {
 
     @Test
     void shouldTreatMinusBetweenValuesAsOperator() {
-        // "5 - 3": the minus follows a value, so it is the subtraction 
operator, not a sign
         assertEquals(
                 List.of(TokenType.NUMBER, TokenType.MINUS, TokenType.NUMBER, 
TokenType.EOF),
                 types("5 - 3"));
@@ -94,7 +83,6 @@ class DataWeaveLexerTest {
 
     @Test
     void shouldTreatMinusAfterOpeningParenAsNegativeNumber() {
-        // "(-3)": previous char is '(', not value-like, so the minus binds to 
the number
         assertEquals(
                 List.of(TokenType.LPAREN, TokenType.NUMBER, TokenType.RPAREN, 
TokenType.EOF),
                 types("(-3)"));
@@ -112,7 +100,6 @@ class DataWeaveLexerTest {
 
     @Test
     void shouldRecognizeHeaderSeparatorAtLineStart() {
-        // the --- on its own line is a header separator, while the negative 
number afterwards stays a number
         List<TokenType> ts = types("%dw 2.0\n---\n-5");
         assertEquals(
                 List.of(TokenType.PERCENT, TokenType.IDENTIFIER, 
TokenType.NUMBER,
@@ -133,7 +120,6 @@ class DataWeaveLexerTest {
 
     @Test
     void shouldTrackLineAndColumnPositions() {
-        // "ab\n  cd": first token at 1:1, second at line 2 after two spaces 
-> 2:3
         List<Token> tokens = tokenize("ab\n  cd");
         assertEquals(1, tokens.get(0).line());
         assertEquals(1, tokens.get(0).col());
@@ -145,7 +131,6 @@ class DataWeaveLexerTest {
 
     @Test
     void shouldSkipUnknownCharactersInsteadOfFailing() {
-        // '@' is not a recognized token; the lexer drops it and keeps going
         assertEquals(
                 List.of(TokenType.IDENTIFIER, TokenType.IDENTIFIER, 
TokenType.EOF),
                 types("a @ b"));
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/transform/DataWeaveParserTest.java
 
b/components/camel-dataweave/src/test/java/org/apache/camel/component/dataweave/DataWeaveParserTest.java
similarity index 74%
rename from 
dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/transform/DataWeaveParserTest.java
rename to 
components/camel-dataweave/src/test/java/org/apache/camel/component/dataweave/DataWeaveParserTest.java
index 8802531c2932..dd8688ed8cb3 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/transform/DataWeaveParserTest.java
+++ 
b/components/camel-dataweave/src/test/java/org/apache/camel/component/dataweave/DataWeaveParserTest.java
@@ -14,31 +14,31 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.dsl.jbang.core.commands.transform;
+package org.apache.camel.component.dataweave;
 
 import java.util.List;
 
-import 
org.apache.camel.dsl.jbang.core.commands.transform.DataWeaveAst.ArrayLit;
-import 
org.apache.camel.dsl.jbang.core.commands.transform.DataWeaveAst.BinaryOp;
-import 
org.apache.camel.dsl.jbang.core.commands.transform.DataWeaveAst.DefaultExpr;
-import 
org.apache.camel.dsl.jbang.core.commands.transform.DataWeaveAst.FieldAccess;
-import 
org.apache.camel.dsl.jbang.core.commands.transform.DataWeaveAst.FunctionCall;
-import 
org.apache.camel.dsl.jbang.core.commands.transform.DataWeaveAst.Identifier;
-import org.apache.camel.dsl.jbang.core.commands.transform.DataWeaveAst.IfElse;
-import 
org.apache.camel.dsl.jbang.core.commands.transform.DataWeaveAst.IndexAccess;
-import org.apache.camel.dsl.jbang.core.commands.transform.DataWeaveAst.Lambda;
-import 
org.apache.camel.dsl.jbang.core.commands.transform.DataWeaveAst.LambdaShorthand;
-import org.apache.camel.dsl.jbang.core.commands.transform.DataWeaveAst.MapExpr;
-import 
org.apache.camel.dsl.jbang.core.commands.transform.DataWeaveAst.NumberLit;
-import 
org.apache.camel.dsl.jbang.core.commands.transform.DataWeaveAst.ObjectLit;
-import org.apache.camel.dsl.jbang.core.commands.transform.DataWeaveAst.Parens;
-import org.apache.camel.dsl.jbang.core.commands.transform.DataWeaveAst.Script;
-import 
org.apache.camel.dsl.jbang.core.commands.transform.DataWeaveAst.StringLit;
-import 
org.apache.camel.dsl.jbang.core.commands.transform.DataWeaveAst.TypeCoercion;
-import org.apache.camel.dsl.jbang.core.commands.transform.DataWeaveAst.UnaryOp;
-import 
org.apache.camel.dsl.jbang.core.commands.transform.DataWeaveAst.Unsupported;
-import org.apache.camel.dsl.jbang.core.commands.transform.DataWeaveAst.VarDecl;
-import org.apache.camel.dsl.jbang.core.commands.transform.DataWeaveLexer.Token;
+import org.apache.camel.component.dataweave.DataWeaveAst.ArrayLit;
+import org.apache.camel.component.dataweave.DataWeaveAst.BinaryOp;
+import org.apache.camel.component.dataweave.DataWeaveAst.DefaultExpr;
+import org.apache.camel.component.dataweave.DataWeaveAst.FieldAccess;
+import org.apache.camel.component.dataweave.DataWeaveAst.FunctionCall;
+import org.apache.camel.component.dataweave.DataWeaveAst.Identifier;
+import org.apache.camel.component.dataweave.DataWeaveAst.IfElse;
+import org.apache.camel.component.dataweave.DataWeaveAst.IndexAccess;
+import org.apache.camel.component.dataweave.DataWeaveAst.Lambda;
+import org.apache.camel.component.dataweave.DataWeaveAst.LambdaShorthand;
+import org.apache.camel.component.dataweave.DataWeaveAst.MapExpr;
+import org.apache.camel.component.dataweave.DataWeaveAst.NumberLit;
+import org.apache.camel.component.dataweave.DataWeaveAst.ObjectLit;
+import org.apache.camel.component.dataweave.DataWeaveAst.Parens;
+import org.apache.camel.component.dataweave.DataWeaveAst.Script;
+import org.apache.camel.component.dataweave.DataWeaveAst.StringLit;
+import org.apache.camel.component.dataweave.DataWeaveAst.TypeCoercion;
+import org.apache.camel.component.dataweave.DataWeaveAst.UnaryOp;
+import org.apache.camel.component.dataweave.DataWeaveAst.Unsupported;
+import org.apache.camel.component.dataweave.DataWeaveAst.VarDecl;
+import org.apache.camel.component.dataweave.DataWeaveLexer.Token;
 import org.junit.jupiter.api.Test;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -47,14 +47,6 @@ import static 
org.junit.jupiter.api.Assertions.assertInstanceOf;
 import static org.junit.jupiter.api.Assertions.assertNull;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
-/**
- * Unit tests for {@link DataWeaveParser}.
- *
- * The parser is recursive descent and best-effort (it never throws on 
malformed input). These tests assert the shape of
- * the produced {@link DataWeaveAst} for representative scripts, with emphasis 
on operator precedence, postfix
- * collection operations, header parsing, and graceful handling of unsupported 
constructs. The AST records are exercised
- * transitively here rather than in a separate test, since they carry no logic 
of their own.
- */
 class DataWeaveParserTest {
 
     private static DataWeaveAst parseExpr(String src) {
@@ -67,7 +59,7 @@ class DataWeaveParserTest {
         return new DataWeaveParser(tokens).parse();
     }
 
-    // ── Header ──
+    // -- Header --
 
     @Test
     void shouldParseHeaderVersionAndOutputType() {
@@ -102,14 +94,13 @@ class DataWeaveParserTest {
 
     @Test
     void shouldDefaultVersionWhenNoHeaderPresent() {
-        // an expression with no %dw header still yields a Script with the 
default 2.0 version
         Script script = assertInstanceOf(Script.class, parseScript("payload"));
         assertEquals("2.0", script.header().version());
         assertNull(script.header().outputType());
         assertInstanceOf(Identifier.class, script.body());
     }
 
-    // ── Literals and field access ──
+    // -- Literals and field access --
 
     @Test
     void shouldParseLiterals() {
@@ -121,7 +112,6 @@ class DataWeaveParserTest {
 
     @Test
     void shouldParseFieldAccessAndIndexAccessChain() {
-        // payload.items[0] -> IndexAccess(FieldAccess(Identifier(payload), 
items), NumberLit(0))
         IndexAccess idx = assertInstanceOf(IndexAccess.class, 
parseExpr("payload.items[0]"));
         assertEquals("0", assertInstanceOf(NumberLit.class, 
idx.index()).value());
         FieldAccess fa = assertInstanceOf(FieldAccess.class, idx.object());
@@ -129,11 +119,10 @@ class DataWeaveParserTest {
         assertEquals("payload", assertInstanceOf(Identifier.class, 
fa.object()).name());
     }
 
-    // ── Precedence ──
+    // -- Precedence --
 
     @Test
     void shouldGiveMultiplicationHigherPrecedenceThanAddition() {
-        // 1 + 2 * 3 -> BinaryOp(+, 1, BinaryOp(*, 2, 3))
         BinaryOp add = assertInstanceOf(BinaryOp.class, parseExpr("1 + 2 * 
3"));
         assertEquals("+", add.op());
         assertEquals("1", assertInstanceOf(NumberLit.class, 
add.left()).value());
@@ -145,7 +134,6 @@ class DataWeaveParserTest {
 
     @Test
     void shouldGiveAndHigherPrecedenceThanOr() {
-        // a and b or c -> BinaryOp(or, BinaryOp(and, a, b), c)
         BinaryOp or = assertInstanceOf(BinaryOp.class, parseExpr("a and b or 
c"));
         assertEquals("or", or.op());
         assertEquals("c", assertInstanceOf(Identifier.class, 
or.right()).name());
@@ -165,16 +153,14 @@ class DataWeaveParserTest {
         assertEquals("+", assertInstanceOf(BinaryOp.class, 
parens.expr()).op());
     }
 
-    // ── Object / array literals ──
+    // -- Object / array literals --
 
     @Test
     void shouldParseObjectLiteralWithStaticAndDynamicKeys() {
         ObjectLit obj = assertInstanceOf(ObjectLit.class, parseExpr("{ name: 
payload.x, (k): v }"));
         assertEquals(2, obj.entries().size());
-        // static key
         assertEquals("name", assertInstanceOf(Identifier.class, 
obj.entries().get(0).key()).name());
         assertFalse(obj.entries().get(0).dynamic());
-        // dynamic key parsed from a parenthesized expression
         assertTrue(obj.entries().get(1).dynamic());
         assertEquals("k", assertInstanceOf(Identifier.class, 
obj.entries().get(1).key()).name());
     }
@@ -186,7 +172,7 @@ class DataWeaveParserTest {
         assertEquals("2", assertInstanceOf(NumberLit.class, 
arr.elements().get(1)).value());
     }
 
-    // ── Collection operations / lambdas ──
+    // -- Collection operations / lambdas --
 
     @Test
     void shouldParseMapWithExplicitLambda() {
@@ -205,7 +191,7 @@ class DataWeaveParserTest {
         assertEquals(List.of("name"), sh.fields());
     }
 
-    // ── Function calls ──
+    // -- Function calls --
 
     @Test
     void shouldParseBuiltinFunctionCall() {
@@ -215,7 +201,7 @@ class DataWeaveParserTest {
         assertEquals("payload", assertInstanceOf(Identifier.class, 
call.args().get(0)).name());
     }
 
-    // ── Type coercion ──
+    // -- Type coercion --
 
     @Test
     void shouldParseTypeCoercionWithoutFormat() {
@@ -231,7 +217,7 @@ class DataWeaveParserTest {
         assertEquals("yyyy-MM-dd", tc.format());
     }
 
-    // ── Control flow ──
+    // -- Control flow --
 
     @Test
     void shouldParseIfElse() {
@@ -250,14 +236,13 @@ class DataWeaveParserTest {
 
     @Test
     void shouldParseVarDeclarationWithTrailingBody() {
-        // "var x = 1 x" -> VarDecl(x, NumberLit(1), body=Identifier(x))
         VarDecl var = assertInstanceOf(VarDecl.class, parseExpr("var x = 1 
x"));
         assertEquals("x", var.name());
         assertEquals("1", assertInstanceOf(NumberLit.class, 
var.value()).value());
         assertEquals("x", assertInstanceOf(Identifier.class, 
var.body()).name());
     }
 
-    // ── Unary ──
+    // -- Unary --
 
     @Test
     void shouldParseLogicalNot() {
@@ -266,7 +251,7 @@ class DataWeaveParserTest {
         assertEquals("a", assertInstanceOf(Identifier.class, 
not.operand()).name());
     }
 
-    // ── Graceful degradation ──
+    // -- Graceful degradation --
 
     @Test
     void shouldRepresentMatchExpressionAsUnsupported() {
@@ -278,7 +263,6 @@ class DataWeaveParserTest {
 
     @Test
     void shouldNotThrowOnUnbalancedInput() {
-        // expect() silently skips a missing RPAREN, so a best-effort AST is 
still produced
         List<Token> tokens = new DataWeaveLexer("(a + b").tokenize();
         assertEquals(DataWeaveLexer.TokenType.EOF, tokens.get(tokens.size() - 
1).type());
         assertInstanceOf(Parens.class, parseExpr("(a + b"));
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/test/resources/dataweave/collection-map.dwl
 b/components/camel-dataweave/src/test/resources/dataweave/collection-map.dwl
similarity index 100%
rename from 
dsl/camel-jbang/camel-jbang-core/src/test/resources/dataweave/collection-map.dwl
rename to 
components/camel-dataweave/src/test/resources/dataweave/collection-map.dwl
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/test/resources/dataweave/event-message.dwl
 b/components/camel-dataweave/src/test/resources/dataweave/event-message.dwl
similarity index 100%
rename from 
dsl/camel-jbang/camel-jbang-core/src/test/resources/dataweave/event-message.dwl
rename to 
components/camel-dataweave/src/test/resources/dataweave/event-message.dwl
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/test/resources/dataweave/null-handling.dwl
 b/components/camel-dataweave/src/test/resources/dataweave/null-handling.dwl
similarity index 100%
rename from 
dsl/camel-jbang/camel-jbang-core/src/test/resources/dataweave/null-handling.dwl
rename to 
components/camel-dataweave/src/test/resources/dataweave/null-handling.dwl
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/test/resources/dataweave/simple-rename.dwl
 b/components/camel-dataweave/src/test/resources/dataweave/simple-rename.dwl
similarity index 100%
rename from 
dsl/camel-jbang/camel-jbang-core/src/test/resources/dataweave/simple-rename.dwl
rename to 
components/camel-dataweave/src/test/resources/dataweave/simple-rename.dwl
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/test/resources/dataweave/string-ops.dwl 
b/components/camel-dataweave/src/test/resources/dataweave/string-ops.dwl
similarity index 100%
rename from 
dsl/camel-jbang/camel-jbang-core/src/test/resources/dataweave/string-ops.dwl
rename to components/camel-dataweave/src/test/resources/dataweave/string-ops.dwl
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/test/resources/dataweave/type-coercion.dwl
 b/components/camel-dataweave/src/test/resources/dataweave/type-coercion.dwl
similarity index 100%
rename from 
dsl/camel-jbang/camel-jbang-core/src/test/resources/dataweave/type-coercion.dwl
rename to 
components/camel-dataweave/src/test/resources/dataweave/type-coercion.dwl
diff --git a/components/pom.xml b/components/pom.xml
index e09d87cfe482..5c9fca05136b 100644
--- a/components/pom.xml
+++ b/components/pom.xml
@@ -120,6 +120,7 @@
         <module>camel-cyberark-vault</module>
         <module>camel-dapr</module>
         <module>camel-datasonnet</module>
+        <module>camel-dataweave</module>
         <module>camel-debug</module>
         <module>camel-diagram</module>
         <module>camel-debezium</module>
diff --git a/docs/components/modules/others/examples/json/dataweave.json 
b/docs/components/modules/others/examples/json/dataweave.json
new file mode 120000
index 000000000000..d2175aae6006
--- /dev/null
+++ b/docs/components/modules/others/examples/json/dataweave.json
@@ -0,0 +1 @@
+../../../../../../components/camel-dataweave/src/generated/resources/dataweave.json
\ No newline at end of file
diff --git a/dsl/camel-jbang/camel-jbang-core/pom.xml 
b/dsl/camel-jbang/camel-jbang-core/pom.xml
index d369b09415b0..d3066b4c5e6f 100644
--- a/dsl/camel-jbang/camel-jbang-core/pom.xml
+++ b/dsl/camel-jbang/camel-jbang-core/pom.xml
@@ -45,6 +45,10 @@
 
     <dependencies>
         <!-- camel -->
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-dataweave</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.apache.camel</groupId>
             <artifactId>camel-diagram</artifactId>
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/TransformDataWeave.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/TransformDataWeave.java
index bc3ff95df84d..e08ed966680f 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/TransformDataWeave.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/TransformDataWeave.java
@@ -23,7 +23,7 @@ import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.List;
 
-import org.apache.camel.dsl.jbang.core.commands.transform.DataWeaveConverter;
+import org.apache.camel.component.dataweave.DataWeaveConverter;
 import picocli.CommandLine;
 import picocli.CommandLine.Command;
 
diff --git a/parent/pom.xml b/parent/pom.xml
index d10f812f6c4d..1030dea51ba4 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -1247,6 +1247,11 @@
                 <artifactId>camel-datasonnet</artifactId>
                 <version>${project.version}</version>
             </dependency>
+            <dependency>
+                <groupId>org.apache.camel</groupId>
+                <artifactId>camel-dataweave</artifactId>
+                <version>${project.version}</version>
+            </dependency>
             <dependency>
                 <groupId>org.apache.camel</groupId>
                 <artifactId>camel-debezium-common</artifactId>

Reply via email to