Skip to content

Commit 81c2da2

Browse files
akoclaude
andcommitted
fix: use comma separators in import/export mapping syntax
Align REST mapping element syntax with database client mappings: comma-separated elements (no trailing comma on last), correct NON-PERSISTENT keyword (hyphen not underscore), proper entity body syntax with parentheses, and no semicolons inside mapping bodies. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 4bb660c commit 81c2da2

File tree

9 files changed

+5711
-5652
lines changed

9 files changed

+5711
-5652
lines changed

.claude/skills/mendix/rest-call-from-json.md

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,10 @@ CREATE IMPORT MAPPING Module.IMM_MyMapping
6969
{
7070
"" AS Module.MyRootObject (Create) {
7171
nestedKey AS Module.MyNestedObject (Create) VIA Module.MyRootObject_MyNestedObject {
72-
name AS name (String)
72+
name AS name (String),
7373
code AS code (String)
74-
}
75-
stringField AS stringField (String)
74+
},
75+
stringField AS stringField (String),
7676
intField AS intField (Integer)
7777
}
7878
};
@@ -170,17 +170,17 @@ CREATE IMPORT MAPPING Integrations.IMM_BibleVerse
170170
{
171171
"" AS Integrations.BibleApiResponse (Create) {
172172
translation AS Integrations.BibleTranslation (Create) VIA Integrations.BibleApiResponse_BibleTranslation {
173-
identifier AS identifier (String)
174-
language AS language (String)
175-
language_code AS language_code (String)
176-
license AS license (String)
173+
identifier AS identifier (String),
174+
language AS language (String),
175+
language_code AS language_code (String),
176+
license AS license (String),
177177
name AS name (String)
178-
}
178+
},
179179
random_verse AS Integrations.BibleVerse (Create) VIA Integrations.BibleApiResponse_BibleVerse {
180-
book AS book (String)
181-
book_id AS book_id (String)
182-
chapter AS chapter (Integer)
183-
text AS text (String)
180+
book AS book (String),
181+
book_id AS book_id (String),
182+
chapter AS chapter (Integer),
183+
text AS text (String),
184184
verse AS verse (Integer)
185185
}
186186
}

mdl-examples/doctype-tests/06-rest-client-examples.mdl

Lines changed: 49 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1199,19 +1199,21 @@ SNIPPET '{"orderId": 100, "customer": {"name": "Alice", "email": "alice@example.
11991199
--
12001200
-- Maps a flat JSON structure to a single non-persistent entity.
12011201

1202-
CREATE ENTITY RestTest.PetResponse (NON_PERSISTENT)
1203-
PetId: Integer;
1204-
Name: String;
1205-
Status: String;
1202+
CREATE NON-PERSISTENT ENTITY RestTest.PetResponse (
1203+
PetId: Integer,
1204+
Name: String,
1205+
Status: String
1206+
);
1207+
/
12061208

12071209
CREATE IMPORT MAPPING RestTest.IMM_Pet
12081210
FROM JSON STRUCTURE RestTest.JSON_Pet
12091211
{
12101212
"" AS RestTest.PetResponse (Create) {
1211-
id AS PetId (Integer, KEY);
1212-
name AS Name (String);
1213-
status AS Status (String);
1214-
};
1213+
id AS PetId (Integer, KEY),
1214+
name AS Name (String),
1215+
status AS Status (String)
1216+
}
12151217
};
12161218

12171219
-- ============================================================================
@@ -1220,41 +1222,49 @@ CREATE IMPORT MAPPING RestTest.IMM_Pet
12201222
--
12211223
-- Maps a nested JSON structure to multiple entities linked by associations.
12221224

1223-
CREATE ENTITY RestTest.OrderResponse (NON_PERSISTENT)
1224-
OrderId: Integer;
1225+
CREATE NON-PERSISTENT ENTITY RestTest.OrderResponse (
1226+
OrderId: Integer
1227+
);
1228+
/
12251229

1226-
CREATE ENTITY RestTest.CustomerInfo (NON_PERSISTENT)
1227-
Name: String;
1228-
Email: String;
1230+
CREATE NON-PERSISTENT ENTITY RestTest.CustomerInfo (
1231+
Name: String,
1232+
Email: String
1233+
);
1234+
/
12291235

1230-
CREATE ENTITY RestTest.OrderItem (NON_PERSISTENT)
1231-
Sku: String;
1232-
Quantity: Integer;
1233-
Price: Decimal;
1236+
CREATE NON-PERSISTENT ENTITY RestTest.OrderItem (
1237+
Sku: String,
1238+
Quantity: Integer,
1239+
Price: Decimal
1240+
);
1241+
/
12341242

12351243
CREATE ASSOCIATION RestTest.OrderResponse_CustomerInfo
12361244
FROM RestTest.OrderResponse
12371245
TO RestTest.CustomerInfo;
1246+
/
12381247

12391248
CREATE ASSOCIATION RestTest.OrderResponse_OrderItem
12401249
FROM RestTest.OrderResponse
12411250
TO RestTest.OrderItem;
1251+
/
12421252

12431253
CREATE IMPORT MAPPING RestTest.IMM_Order
12441254
FROM JSON STRUCTURE RestTest.JSON_Order
12451255
{
12461256
"" AS RestTest.OrderResponse (Create) {
1247-
orderId AS OrderId (Integer, KEY);
1257+
orderId AS OrderId (Integer, KEY),
12481258
customer AS RestTest.CustomerInfo (Create) VIA RestTest.OrderResponse_CustomerInfo {
1249-
email AS Email (String);
1250-
name AS Name (String);
1251-
};
1259+
email AS Email (String),
1260+
name AS Name (String)
1261+
},
12521262
items AS RestTest.OrderItem (Create) VIA RestTest.OrderResponse_OrderItem {
1253-
price AS Price (Decimal);
1254-
quantity AS Quantity (Integer);
1255-
sku AS Sku (String);
1256-
};
1257-
};
1263+
price AS Price (Decimal),
1264+
quantity AS Quantity (Integer),
1265+
sku AS Sku (String)
1266+
}
1267+
}
12581268
};
12591269

12601270
-- ############################################################################
@@ -1273,10 +1283,10 @@ CREATE EXPORT MAPPING RestTest.EMM_Pet
12731283
TO JSON STRUCTURE RestTest.JSON_Pet
12741284
{
12751285
RestTest.PetResponse AS root {
1276-
PetId AS id (Integer);
1277-
Name AS name (String);
1278-
Status AS status (String);
1279-
};
1286+
PetId AS id (Integer),
1287+
Name AS name (String),
1288+
Status AS status (String)
1289+
}
12801290
};
12811291

12821292
-- ============================================================================
@@ -1290,17 +1300,17 @@ CREATE EXPORT MAPPING RestTest.EMM_Order
12901300
NULL VALUES LeaveOutElement
12911301
{
12921302
RestTest.OrderResponse AS root {
1293-
OrderId AS orderId (Integer);
1303+
OrderId AS orderId (Integer),
12941304
RestTest.CustomerInfo VIA RestTest.OrderResponse_CustomerInfo AS customer {
1295-
Email AS email (String);
1296-
Name AS name (String);
1297-
};
1305+
Email AS email (String),
1306+
Name AS name (String)
1307+
},
12981308
RestTest.OrderItem VIA RestTest.OrderResponse_OrderItem AS items {
1299-
Price AS price (Decimal);
1300-
Quantity AS quantity (Integer);
1301-
Sku AS sku (String);
1302-
};
1303-
};
1309+
Price AS price (Decimal),
1310+
Quantity AS quantity (Integer),
1311+
Sku AS sku (String)
1312+
}
1313+
}
13041314
};
13051315

13061316
-- ############################################################################

mdl/executor/cmd_export_mappings.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ func (e *Executor) describeExportMapping(name ast.QualifiedName) error {
132132
fmt.Fprintln(e.output, "{")
133133
for _, elem := range em.Elements {
134134
printExportMappingElement(e, elem, 1)
135-
fmt.Fprintln(e.output, ";")
135+
fmt.Fprintln(e.output)
136136
}
137137
fmt.Fprintln(e.output, "};")
138138
}
@@ -148,9 +148,13 @@ func printExportMappingElement(e *Executor, elem *model.ExportMappingElement, de
148148
}
149149
if len(elem.Children) > 0 {
150150
fmt.Fprintf(e.output, "%s%s%s AS %s {\n", indent, elem.Entity, via, elem.ExposedName)
151-
for _, child := range elem.Children {
151+
for i, child := range elem.Children {
152152
printExportMappingElement(e, child, depth+1)
153-
fmt.Fprintln(e.output, ";")
153+
if i < len(elem.Children)-1 {
154+
fmt.Fprintln(e.output, ",")
155+
} else {
156+
fmt.Fprintln(e.output)
157+
}
154158
}
155159
fmt.Fprintf(e.output, "%s}", indent)
156160
} else {

mdl/executor/cmd_import_mappings.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ func (e *Executor) describeImportMapping(name ast.QualifiedName) error {
128128
fmt.Fprintln(e.output, "{")
129129
for _, elem := range im.Elements {
130130
printImportMappingElement(e, elem, 1)
131-
fmt.Fprintln(e.output, ";")
131+
fmt.Fprintln(e.output)
132132
}
133133
fmt.Fprintln(e.output, "};")
134134
}
@@ -155,9 +155,13 @@ func printImportMappingElement(e *Executor, elem *model.ImportMappingElement, de
155155
}
156156
if len(elem.Children) > 0 {
157157
fmt.Fprintf(e.output, "%s%s AS %s (%s)%s {\n", indent, jsonKey, entityOrName, handling, via)
158-
for _, child := range elem.Children {
158+
for i, child := range elem.Children {
159159
printImportMappingElement(e, child, depth+1)
160-
fmt.Fprintln(e.output, ";")
160+
if i < len(elem.Children)-1 {
161+
fmt.Fprintln(e.output, ",")
162+
} else {
163+
fmt.Fprintln(e.output)
164+
}
161165
}
162166
fmt.Fprintf(e.output, "%s}", indent)
163167
} else {

mdl/executor/roundtrip_export_mapping_test.go

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ func TestRoundtripExportMapping_NoSchema(t *testing.T) {
2525

2626
createMDL := `CREATE EXPORT MAPPING ` + testModule + `.ExportPetBasic {
2727
` + testModule + `.EMPet AS Root {
28-
Id AS id (Integer);
29-
Name AS name (String);
30-
};
28+
Id AS id (Integer),
29+
Name AS name (String)
30+
}
3131
};`
3232

3333
env.assertContains(createMDL, []string{
@@ -58,9 +58,9 @@ SNIPPET '{"orderId": 1, "total": 99.99}';`); err != nil {
5858
TO JSON STRUCTURE ` + testModule + `.EMOrderJS
5959
{
6060
` + testModule + `.EMOrder AS Root {
61-
OrderId AS orderId (Integer);
62-
Total AS total (Decimal);
63-
};
61+
OrderId AS orderId (Integer),
62+
Total AS total (Decimal)
63+
}
6464
};`
6565

6666
env.assertContains(createMDL, []string{
@@ -87,8 +87,8 @@ func TestRoundtripExportMapping_NullValueOption(t *testing.T) {
8787
NULL VALUES SendAsNil
8888
{
8989
` + testModule + `.EMNullPet AS Root {
90-
Id AS id (Integer);
91-
};
90+
Id AS id (Integer)
91+
}
9292
};`); err != nil {
9393
t.Fatalf("CREATE EXPORT MAPPING failed: %v", err)
9494
}
@@ -115,8 +115,8 @@ func TestRoundtripExportMapping_Drop(t *testing.T) {
115115

116116
if err := env.executeMDL(`CREATE EXPORT MAPPING ` + testModule + `.ToDropEM {
117117
` + testModule + `.EMDropPet AS Root {
118-
Id AS id (Integer);
119-
};
118+
Id AS id (Integer)
119+
}
120120
};`); err != nil {
121121
t.Fatalf("CREATE EXPORT MAPPING failed: %v", err)
122122
}
@@ -146,8 +146,8 @@ func TestRoundtripExportMapping_ShowAppearsInList(t *testing.T) {
146146

147147
if err := env.executeMDL(`CREATE EXPORT MAPPING ` + testModule + `.ListableEM {
148148
` + testModule + `.EMListPet AS Root {
149-
Id AS id (Integer);
150-
};
149+
Id AS id (Integer)
150+
}
151151
};`); err != nil {
152152
t.Fatalf("CREATE EXPORT MAPPING failed: %v", err)
153153
}
@@ -181,9 +181,9 @@ func TestMxCheck_ExportMapping_Basic(t *testing.T) {
181181

182182
if err := env.executeMDL(`CREATE EXPORT MAPPING ` + testModule + `.MxCheckExportPet {
183183
` + testModule + `.MxCheckEMPet AS Root {
184-
Id AS id (Integer);
185-
Name AS name (String);
186-
};
184+
Id AS id (Integer),
185+
Name AS name (String)
186+
}
187187
};`); err != nil {
188188
t.Fatalf("CREATE EXPORT MAPPING failed: %v", err)
189189
}

mdl/executor/roundtrip_import_mapping_test.go

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ func TestRoundtripImportMapping_NoSchema(t *testing.T) {
2525

2626
createMDL := `CREATE IMPORT MAPPING ` + testModule + `.ImportPetBasic {
2727
"" AS ` + testModule + `.IMPet (Create) {
28-
id AS Id (Integer, KEY);
29-
name AS Name (String);
30-
};
28+
id AS Id (Integer, KEY),
29+
name AS Name (String)
30+
}
3131
};`
3232

3333
env.assertContains(createMDL, []string{
@@ -59,9 +59,9 @@ SNIPPET '{"orderId": 1, "total": 99.99}';`); err != nil {
5959
FROM JSON STRUCTURE ` + testModule + `.OrderJS
6060
{
6161
"" AS ` + testModule + `.IMOrder (Create) {
62-
orderId AS OrderId (Integer, KEY);
63-
total AS Total (Decimal);
64-
};
62+
orderId AS OrderId (Integer, KEY),
63+
total AS Total (Decimal)
64+
}
6565
};`
6666

6767
env.assertContains(createMDL, []string{
@@ -89,11 +89,11 @@ func TestRoundtripImportMapping_ValueTypes(t *testing.T) {
8989

9090
createMDL := `CREATE IMPORT MAPPING ` + testModule + `.ImportAllTypes {
9191
"" AS ` + testModule + `.IMAllTypes (Create) {
92-
intVal AS IntVal (Integer, KEY);
93-
decVal AS DecVal (Decimal);
94-
boolVal AS BoolVal (Boolean);
95-
dateVal AS DateVal (DateTime);
96-
};
92+
intVal AS IntVal (Integer, KEY),
93+
decVal AS DecVal (Decimal),
94+
boolVal AS BoolVal (Boolean),
95+
dateVal AS DateVal (DateTime)
96+
}
9797
};`
9898

9999
env.assertContains(createMDL, []string{
@@ -116,8 +116,8 @@ func TestRoundtripImportMapping_Drop(t *testing.T) {
116116

117117
if err := env.executeMDL(`CREATE IMPORT MAPPING ` + testModule + `.ToDropIM {
118118
"" AS ` + testModule + `.IMDropPet (Create) {
119-
id AS Id (Integer, KEY);
120-
};
119+
id AS Id (Integer, KEY)
120+
}
121121
};`); err != nil {
122122
t.Fatalf("CREATE IMPORT MAPPING failed: %v", err)
123123
}
@@ -147,8 +147,8 @@ func TestRoundtripImportMapping_ShowAppearsInList(t *testing.T) {
147147

148148
if err := env.executeMDL(`CREATE IMPORT MAPPING ` + testModule + `.ListableIM {
149149
"" AS ` + testModule + `.IMListPet (Create) {
150-
id AS Id (Integer, KEY);
151-
};
150+
id AS Id (Integer, KEY)
151+
}
152152
};`); err != nil {
153153
t.Fatalf("CREATE IMPORT MAPPING failed: %v", err)
154154
}
@@ -182,9 +182,9 @@ func TestMxCheck_ImportMapping_Basic(t *testing.T) {
182182

183183
if err := env.executeMDL(`CREATE IMPORT MAPPING ` + testModule + `.MxCheckImportPet {
184184
"" AS ` + testModule + `.MxCheckIMPet (Create) {
185-
id AS Id (Integer, KEY);
186-
name AS Name (String);
187-
};
185+
id AS Id (Integer, KEY),
186+
name AS Name (String)
187+
}
188188
};`); err != nil {
189189
t.Fatalf("CREATE IMPORT MAPPING failed: %v", err)
190190
}

0 commit comments

Comments
 (0)