diff --git a/mdl-examples/doctype-tests/01-domain-model-examples.mdl b/mdl-examples/doctype-tests/01-domain-model-examples.mdl index 562c8f95..11e07a6d 100644 --- a/mdl-examples/doctype-tests/01-domain-model-examples.mdl +++ b/mdl-examples/doctype-tests/01-domain-model-examples.mdl @@ -1692,7 +1692,7 @@ create persistent entity DmTest.Attachment extends System.FileDocument ( * plus adds metadata for product catalog display. */ @position(2300, 200) -create persistent entity DmTest.ProductPhoto extends System.image ( +create persistent entity DmTest.ProductPhoto extends System.Image ( /** Photo caption for display */ PhotoCaption: string(200), /** Display sort order */ @@ -1784,7 +1784,7 @@ create persistent entity DmTest.InternalDocument extends System.FileDocument; * Both keywords are supported; EXTENDS is preferred for new code. */ @position(2300, 600) -create persistent entity DmTest.ProfilePhoto generalization System.image ( +create persistent entity DmTest.ProfilePhoto generalization System.Image ( /** Whether this photo has been approved by admin */ IsApproved: boolean default false ); diff --git a/mdl-examples/doctype-tests/06-rest-client-examples.mdl b/mdl-examples/doctype-tests/06-rest-client-examples.mdl index 65143ce1..3eff5021 100644 --- a/mdl-examples/doctype-tests/06-rest-client-examples.mdl +++ b/mdl-examples/doctype-tests/06-rest-client-examples.mdl @@ -793,7 +793,7 @@ begin -- $latestHttpResponse is a system variable (System.HttpResponse) that is -- automatically populated after SEND REST REQUEST. Check its Content -- attribute to determine if the call returned data. - if $latestHttpResponse/content != empty then + if $latestHttpResponse/Content != empty then set $success = true; log info node 'RestTest' 'ACT_TestHeaders: headers echoed'; else diff --git a/mdl-examples/doctype-tests/08-security-examples.mdl b/mdl-examples/doctype-tests/08-security-examples.mdl index b3b32e3d..7f6395f1 100644 --- a/mdl-examples/doctype-tests/08-security-examples.mdl +++ b/mdl-examples/doctype-tests/08-security-examples.mdl @@ -191,11 +191,11 @@ describe user role 'Administrator'; /** * Create a simple module role without description. */ -create module role SecTest.user; +create module role SecTest.User; / -- Describe a specific module role (shows DDL + which user roles include it) -describe module role SecTest.user; +describe module role SecTest.User; -- ============================================================================ -- Level 2.2: Module Role with Description @@ -235,7 +235,7 @@ create module role SecTest.Viewer description 'Read-only access for viewing data /** * Allow the User role to execute the customer creation microflow. */ -grant execute on microflow SecTest.ACT_Customer_Create to SecTest.user; +grant execute on microflow SecTest.ACT_Customer_Create to SecTest.User; / -- Verify the grant @@ -249,7 +249,7 @@ show access on microflow SecTest.ACT_Customer_Create; /** * Allow both User and Administrator roles to process orders. */ -grant execute on microflow SecTest.ACT_Order_Process to SecTest.user, SecTest.Administrator; +grant execute on microflow SecTest.ACT_Order_Process to SecTest.User, SecTest.Administrator; / -- ============================================================================ @@ -269,7 +269,7 @@ grant execute on microflow SecTest.ACT_Customer_Delete to SecTest.Administrator; /** * Remove User's ability to process orders (admin-only now). */ -revoke execute on microflow SecTest.ACT_Order_Process from SecTest.user; +revoke execute on microflow SecTest.ACT_Order_Process from SecTest.User; / -- Verify the revoke @@ -290,7 +290,7 @@ revoke execute on microflow SecTest.ACT_Customer_Delete from SecTest.Administrat /** * Granting a role that already has access is a no-op (safe to repeat). */ -grant execute on microflow SecTest.ACT_Customer_Create to SecTest.user; +grant execute on microflow SecTest.ACT_Customer_Create to SecTest.User; / @@ -308,7 +308,7 @@ grant execute on microflow SecTest.ACT_Customer_Create to SecTest.user; /** * Allow users to view the customer overview page. */ -grant view on page SecTest.Customer_Overview to SecTest.user; +grant view on page SecTest.Customer_Overview to SecTest.User; / -- Verify @@ -322,7 +322,7 @@ show access on page SecTest.Customer_Overview; /** * Allow both users and administrators to view orders. */ -grant view on page SecTest.Order_Overview to SecTest.user, SecTest.Administrator; +grant view on page SecTest.Order_Overview to SecTest.User, SecTest.Administrator; / -- ============================================================================ @@ -332,7 +332,7 @@ grant view on page SecTest.Order_Overview to SecTest.user, SecTest.Administrator /** * Remove User's view access on order overview (admin-only now). */ -revoke view on page SecTest.Order_Overview from SecTest.user; +revoke view on page SecTest.Order_Overview from SecTest.User; / -- Verify - should only show Administrator @@ -374,7 +374,7 @@ grant SecTest.Viewer on SecTest.Customer (read *); /** * Grant read access to specific attributes, write to a subset. */ -grant SecTest.user on SecTest.Customer (read (Name, Email), write (Email)); +grant SecTest.User on SecTest.Customer (read (Name, Email), write (Email)); / -- ============================================================================ @@ -384,7 +384,7 @@ grant SecTest.user on SecTest.Customer (read (Name, Email), write (Email)); /** * Grant access only to active customers using an XPath constraint. */ -grant SecTest.user on SecTest.Order (read *, write *) where '[Status = ''Open'']'; +grant SecTest.User on SecTest.Order (read *, write *) where '[Status = ''Open'']'; / -- Verify entity access @@ -398,7 +398,7 @@ show access on SecTest.Customer; /** * GRANT is additive: adding Notes access preserves existing Name and Email. */ -grant SecTest.user on SecTest.Customer (read (Notes)); +grant SecTest.User on SecTest.Customer (read (Notes)); / -- ============================================================================ @@ -409,13 +409,13 @@ grant SecTest.user on SecTest.Customer (read (Notes)); * Remove read access on a specific attribute (Notes). * Other permissions are preserved. */ -revoke SecTest.user on SecTest.Customer (read (Notes)); +revoke SecTest.User on SecTest.Customer (read (Notes)); / /** * Downgrade write to read-only on Email. */ -revoke SecTest.user on SecTest.Customer (write (Email)); +revoke SecTest.User on SecTest.Customer (write (Email)); / -- ============================================================================ @@ -446,7 +446,7 @@ show access on SecTest.Customer; /** * Create a user role and assign a single module role. */ -create or modify user role RegularUser (System.user, SecTest.user); +create or modify user role RegularUser (System.User, SecTest.User); / -- ============================================================================ @@ -456,7 +456,7 @@ create or modify user role RegularUser (System.user, SecTest.user); /** * A user role can include roles from multiple modules. */ -create or modify user role PowerUser (System.user, SecTest.user, SecTest.Administrator); +create or modify user role PowerUser (System.User, SecTest.User, SecTest.Administrator); / -- ============================================================================ @@ -607,7 +607,7 @@ create module role SecTest.Manager description 'Can manage customers and orders' * Step 2: Grant microflow access based on roles. * Users can create customers, managers and admins can do everything. */ -grant execute on microflow SecTest.ACT_Customer_Create to SecTest.user, SecTest.Manager; +grant execute on microflow SecTest.ACT_Customer_Create to SecTest.User, SecTest.Manager; grant execute on microflow SecTest.ACT_Customer_Delete to SecTest.Manager, SecTest.Administrator; grant execute on microflow SecTest.ACT_Order_Process to SecTest.Manager, SecTest.Administrator; / @@ -616,7 +616,7 @@ grant execute on microflow SecTest.ACT_Order_Process to SecTest.Manager, SecTest * Step 3: Grant page access based on roles. * All roles can see customers, only managers+ can see orders. */ -grant view on page SecTest.Customer_Overview to SecTest.user, SecTest.Manager, SecTest.Administrator; +grant view on page SecTest.Customer_Overview to SecTest.User, SecTest.Manager, SecTest.Administrator; grant view on page SecTest.Order_Overview to SecTest.Manager, SecTest.Administrator; / @@ -648,8 +648,8 @@ show access on page SecTest.Order_Overview; -- When a module has partial access rules (not all entities covered by all -- roles), MxBuild reports CE0066 regardless of security level. revoke SecTest.Administrator on SecTest.Customer; -revoke SecTest.user on SecTest.Customer; -revoke SecTest.user on SecTest.Order; +revoke SecTest.User on SecTest.Customer; +revoke SecTest.User on SecTest.Order; revoke SecTest.Manager on SecTest.Customer; diff --git a/mdl-examples/doctype-tests/12-styling-examples.mdl b/mdl-examples/doctype-tests/12-styling-examples.mdl index 25f53505..852ddb7a 100644 --- a/mdl-examples/doctype-tests/12-styling-examples.mdl +++ b/mdl-examples/doctype-tests/12-styling-examples.mdl @@ -154,7 +154,7 @@ create page StyleTest.P003_Design_Properties ( title: 'Design Properties', layout: Atlas_Core.Atlas_Default, - url: 'style_003_design_properties/{Task}', + url: 'style_003_design_properties/{task}', params: { $task: StyleTest.task } ) { diff --git a/mdl-examples/doctype-tests/14-project-settings-examples.mdl b/mdl-examples/doctype-tests/14-project-settings-examples.mdl index e55ea639..68e93025 100644 --- a/mdl-examples/doctype-tests/14-project-settings-examples.mdl +++ b/mdl-examples/doctype-tests/14-project-settings-examples.mdl @@ -124,7 +124,7 @@ drop configuration 'Staging'; /** * Example 4.1: Set default language */ -alter settings LANGUAGE DefaultLanguageCode = 'en_US'; +alter settings language DefaultLanguageCode = 'en_US'; /** * Example 4.2: Configure workflow settings diff --git a/mdl-examples/doctype-tests/alter-workflow.mdl b/mdl-examples/doctype-tests/alter-workflow.mdl index d5c562e6..ca2b6c2e 100644 --- a/mdl-examples/doctype-tests/alter-workflow.mdl +++ b/mdl-examples/doctype-tests/alter-workflow.mdl @@ -65,13 +65,13 @@ end; -- Targeting microflow: (System.Workflow, context) -> List of System.User create microflow WFTest.ACT_TargetUsers ( - $workflow: System.workflow, + $workflow: System.Workflow, $context: WFTest.OrderContext ) -returns list of System.user as $users +returns list of System.User as $users begin @position(200,200) - retrieve $users from System.user; + retrieve $users from System.User; @position(400,200) return $users; end; / @@ -109,7 +109,7 @@ create page WFTest.AlternateTaskPage ( create page WFTest.OverviewPage ( title: 'Workflow Overview', layout: Atlas_Core.Atlas_Default, - params: { $workflow: System.workflow } + params: { $workflow: System.Workflow } ) { layoutgrid g1 { row r1 { diff --git a/mdl-examples/doctype-tests/workflow-microflow-actions.mdl b/mdl-examples/doctype-tests/workflow-microflow-actions.mdl index 42e1cd96..084708ac 100644 --- a/mdl-examples/doctype-tests/workflow-microflow-actions.mdl +++ b/mdl-examples/doctype-tests/workflow-microflow-actions.mdl @@ -29,7 +29,7 @@ end workflow; -- ############################################################################ create microflow TestModule.MF_WorkflowActions ( - $workflow: System.workflow, + $workflow: System.Workflow, $ContextObj: TestModule.DeliveryContext, $UserTask: System.WorkflowUserTask ) diff --git a/mdl-examples/mes/02-catalog-domain-model.mdl b/mdl-examples/mes/02-catalog-domain-model.mdl index 99e149ab..a6ecc369 100644 --- a/mdl-examples/mes/02-catalog-domain-model.mdl +++ b/mdl-examples/mes/02-catalog-domain-model.mdl @@ -151,7 +151,7 @@ index (SKU); */ @position(350, 250) create persistent entity ProductCatalog.ProductImage -extends System.image ( +extends System.Image ( /** Caption describing the image */ ImageCaption: string(500), /** Whether this is the primary display image */ diff --git a/mdl/backend/mpr/workflow_mutator.go b/mdl/backend/mpr/workflow_mutator.go index 41126346..4e7b86e2 100644 --- a/mdl/backend/mpr/workflow_mutator.go +++ b/mdl/backend/mpr/workflow_mutator.go @@ -85,11 +85,11 @@ func (m *mprWorkflowMutator) SetProperty(prop string, value string) error { } return nil - case "EXPORT_LEVEL": + case "export_level": dSet(m.rawData, "ExportLevel", value) return nil - case "DUE_DATE": + case "due_date": dSet(m.rawData, "DueDate", value) return nil @@ -100,7 +100,7 @@ func (m *mprWorkflowMutator) SetProperty(prop string, value string) error { func (m *mprWorkflowMutator) SetPropertyWithEntity(prop string, value string, entity string) error { switch prop { - case "OVERVIEW_PAGE": + case "overview_page": if value == "" { dSet(m.rawData, "AdminPage", nil) } else { @@ -180,7 +180,7 @@ func (m *mprWorkflowMutator) SetActivityProperty(activityRef string, atPos int, } return nil - case "TARGETING_MICROFLOW": + case "targeting_microflow": userTargeting := bson.D{ {Key: "$ID", Value: bsonutil.NewIDBsonBinary()}, {Key: "$Type", Value: "Workflows$MicroflowUserTargeting"}, @@ -189,7 +189,7 @@ func (m *mprWorkflowMutator) SetActivityProperty(activityRef string, atPos int, dSet(actDoc, "UserTargeting", userTargeting) return nil - case "TARGETING_XPATH": + case "targeting_xpath": userTargeting := bson.D{ {Key: "$ID", Value: bsonutil.NewIDBsonBinary()}, {Key: "$Type", Value: "Workflows$XPathUserTargeting"}, @@ -198,7 +198,7 @@ func (m *mprWorkflowMutator) SetActivityProperty(activityRef string, atPos int, dSet(actDoc, "UserTargeting", userTargeting) return nil - case "DUE_DATE": + case "due_date": dSet(actDoc, "DueDate", value) return nil diff --git a/mdl/backend/mpr/workflow_mutator_test.go b/mdl/backend/mpr/workflow_mutator_test.go index cfef7d3b..09a50a09 100644 --- a/mdl/backend/mpr/workflow_mutator_test.go +++ b/mdl/backend/mpr/workflow_mutator_test.go @@ -183,7 +183,7 @@ func TestWorkflowMutator_SetProperty_ExportLevel(t *testing.T) { doc = append(doc, bson.E{Key: "ExportLevel", Value: "Usable"}) m := newMutator(doc) - if err := m.SetProperty("EXPORT_LEVEL", "Hidden"); err != nil { + if err := m.SetProperty("export_level", "Hidden"); err != nil { t.Fatalf("SetProperty EXPORT_LEVEL failed: %v", err) } if got := dGetString(m.rawData, "ExportLevel"); got != "Hidden" { @@ -436,7 +436,7 @@ func TestWorkflowMutator_SetActivityProperty_DueDate(t *testing.T) { act = append(act, bson.E{Key: "DueDate", Value: ""}) m := newMutator(makeWorkflowDoc(act)) - if err := m.SetActivityProperty("Review", 0, "DUE_DATE", "${PT48H}"); err != nil { + if err := m.SetActivityProperty("Review", 0, "due_date", "${PT48H}"); err != nil { t.Fatalf("SetActivityProperty DUE_DATE failed: %v", err) } @@ -1220,7 +1220,7 @@ func TestWorkflowMutator_SetActivityProperty_TargetingMicroflow(t *testing.T) { act = append(act, bson.E{Key: "UserTargeting", Value: nil}) m := newMutator(makeWorkflowDoc(act)) - if err := m.SetActivityProperty("Review", 0, "TARGETING_MICROFLOW", "MyModule.AssignReviewer"); err != nil { + if err := m.SetActivityProperty("Review", 0, "targeting_microflow", "MyModule.AssignReviewer"); err != nil { t.Fatalf("SetActivityProperty TARGETING_MICROFLOW failed: %v", err) } @@ -1242,7 +1242,7 @@ func TestWorkflowMutator_SetActivityProperty_TargetingXPath(t *testing.T) { act = append(act, bson.E{Key: "UserTargeting", Value: nil}) m := newMutator(makeWorkflowDoc(act)) - if err := m.SetActivityProperty("Review", 0, "TARGETING_XPATH", "[Role = 'Admin']"); err != nil { + if err := m.SetActivityProperty("Review", 0, "targeting_xpath", "[Role = 'Admin']"); err != nil { t.Fatalf("SetActivityProperty TARGETING_XPATH failed: %v", err) } @@ -1265,7 +1265,7 @@ func TestWorkflowMutator_SetPropertyWithEntity_OverviewPage(t *testing.T) { doc = append(doc, bson.E{Key: "AdminPage", Value: nil}) m := newMutator(doc) - if err := m.SetPropertyWithEntity("OVERVIEW_PAGE", "MyModule.OverviewPage", ""); err != nil { + if err := m.SetPropertyWithEntity("overview_page", "MyModule.OverviewPage", ""); err != nil { t.Fatalf("SetPropertyWithEntity OVERVIEW_PAGE failed: %v", err) } @@ -1285,7 +1285,7 @@ func TestWorkflowMutator_SetPropertyWithEntity_OverviewPage_Clear(t *testing.T) }}) m := newMutator(doc) - if err := m.SetPropertyWithEntity("OVERVIEW_PAGE", "", ""); err != nil { + if err := m.SetPropertyWithEntity("overview_page", "", ""); err != nil { t.Fatalf("SetPropertyWithEntity clear failed: %v", err) } diff --git a/mdl/executor/cmd_alter_workflow.go b/mdl/executor/cmd_alter_workflow.go index 9e970d54..d9416ac2 100644 --- a/mdl/executor/cmd_alter_workflow.go +++ b/mdl/executor/cmd_alter_workflow.go @@ -62,8 +62,8 @@ func execAlterWorkflow(ctx *ExecContext, s *ast.AlterWorkflowStmt) error { switch o := op.(type) { case *ast.SetWorkflowPropertyOp: switch o.Property { - case "OVERVIEW_PAGE": - // OVERVIEW_PAGE uses Entity as the page qualified name (Value is unused). + case "overview_page": + // overview_page uses Entity as the page qualified name (Value is unused). qn := o.Entity.Module + "." + o.Entity.Name if qn == "." { qn = "" @@ -91,7 +91,7 @@ func execAlterWorkflow(ctx *ExecContext, s *ast.AlterWorkflowStmt) error { switch o.Property { case "page": value = o.PageName.Module + "." + o.PageName.Name - case "TARGETING_MICROFLOW": + case "targeting_microflow": value = o.Microflow.Module + "." + o.Microflow.Name } if err := mutator.SetActivityProperty(o.ActivityRef, o.AtPosition, o.Property, value); err != nil { diff --git a/mdl/executor/cmd_businessevents.go b/mdl/executor/cmd_businessevents.go index 827c5bec..e5f2b04c 100644 --- a/mdl/executor/cmd_businessevents.go +++ b/mdl/executor/cmd_businessevents.go @@ -331,7 +331,7 @@ func createBusinessEventService(ctx *ExecContext, stmt *ast.CreateBusinessEventS msg.TypeName = "BusinessEvents$Message" // Set publish/subscribe based on operation - switch strings.ToUpper(msgDef.Operation) { + switch strings.ToLower(msgDef.Operation) { case "publish": msg.CanSubscribe = true // Service publishes → others subscribe case "subscribe": diff --git a/mdl/executor/cmd_catalog.go b/mdl/executor/cmd_catalog.go index 86763a63..d29e1551 100644 --- a/mdl/executor/cmd_catalog.go +++ b/mdl/executor/cmd_catalog.go @@ -655,7 +655,7 @@ func captureDescribe(ctx *ExecContext, objectType string, qualifiedName string) defer func() { ctx.Output = origOutput }() var err error - switch strings.ToUpper(objectType) { + switch strings.ToLower(objectType) { case "entity": err = describeEntity(ctx, qn) case "microflow", "nanoflow": @@ -713,7 +713,7 @@ func captureDescribeParallel(ctx *ExecContext, objectType string, qualifiedName } var err error - switch strings.ToUpper(objectType) { + switch strings.ToLower(objectType) { case "entity": err = describeEntity(localCtx, qn) case "microflow", "nanoflow": diff --git a/mdl/executor/cmd_diff_mdl.go b/mdl/executor/cmd_diff_mdl.go index 4fd25c5e..e602e1a4 100644 --- a/mdl/executor/cmd_diff_mdl.go +++ b/mdl/executor/cmd_diff_mdl.go @@ -350,7 +350,7 @@ func microflowStatementToMDL(ctx *ExecContext, stmt ast.MicroflowStatement, inde nodeStr = "'" + nodeStr + "'" } msgStr := diffExpressionToString(ctx, s.Message) - stmt := fmt.Sprintf("%slog %s node %s %s", indentStr, strings.ToUpper(s.Level.String()), nodeStr, msgStr) + stmt := fmt.Sprintf("%slog %s node %s %s", indentStr, strings.ToLower(s.Level.String()), nodeStr, msgStr) if len(s.Template) > 0 { var params []string for _, p := range s.Template { diff --git a/mdl/executor/cmd_entities_describe.go b/mdl/executor/cmd_entities_describe.go index e6015a4c..4dc57500 100644 --- a/mdl/executor/cmd_entities_describe.go +++ b/mdl/executor/cmd_entities_describe.go @@ -402,12 +402,7 @@ func describeEntity(ctx *ExecContext, name ast.QualifiedName) error { if mfName == "" { continue } - eventName := string(eh.Event) - if eventName == "RollBack" { - eventName = "rollback" - } else { - eventName = strings.ToUpper(eventName) - } + eventName := strings.ToLower(string(eh.Event)) // Show parameter: ($currentObject) or () paramStr := "()" if eh.PassEventObject { @@ -419,7 +414,7 @@ func describeEntity(ctx *ExecContext, name ast.QualifiedName) error { options = " raise error" } fmt.Fprintf(ctx.Output, "\non %s %s call %s%s%s", - strings.ToUpper(string(eh.Moment)), eventName, mfName, paramStr, options) + strings.ToLower(string(eh.Moment)), eventName, mfName, paramStr, options) } fmt.Fprintln(ctx.Output, ";") diff --git a/mdl/executor/cmd_mermaid.go b/mdl/executor/cmd_mermaid.go index baf0af02..3e597a01 100644 --- a/mdl/executor/cmd_mermaid.go +++ b/mdl/executor/cmd_mermaid.go @@ -30,8 +30,8 @@ func describeMermaid(ctx *ExecContext, objectType, name string) error { qn = ast.QualifiedName{Module: name} } - switch strings.ToUpper(objectType) { - case "entity", "DOMAINMODEL": + switch strings.ToLower(objectType) { + case "entity", "domainmodel": return domainModelToMermaid(ctx, qn.Module) case "microflow": return microflowToMermaid(ctx, qn) diff --git a/mdl/executor/cmd_pages_builder_v3.go b/mdl/executor/cmd_pages_builder_v3.go index c367bbf4..686b45db 100644 --- a/mdl/executor/cmd_pages_builder_v3.go +++ b/mdl/executor/cmd_pages_builder_v3.go @@ -257,7 +257,7 @@ func (pb *pageBuilder) buildWidgetV3(w *ast.WidgetV3) (pages.Widget, error) { var widget pages.Widget var err error - switch strings.ToUpper(w.Type) { + switch strings.ToLower(w.Type) { case "dataview": widget, err = pb.buildDataViewV3(w) case "datagrid": @@ -419,7 +419,7 @@ func applyWidgetAppearance(widget pages.Widget, w *ast.WidgetV3, theme *ThemeReg if len(astProps) > 0 { var dpValues []pages.DesignPropertyValue for _, p := range astProps { - switch strings.ToUpper(p.Value) { + switch strings.ToLower(p.Value) { case "on": dpValues = append(dpValues, pages.DesignPropertyValue{ Key: p.Key, @@ -533,7 +533,7 @@ func (pb *pageBuilder) buildDataSourceV3(ds *ast.DataSourceV3) (pages.DataSource // Handle ORDER BY for _, ob := range ds.OrderBy { direction := pages.SortDirectionAscending - if strings.ToUpper(ob.Direction) == "desc" { + if strings.ToLower(ob.Direction) == "desc" { direction = pages.SortDirectionDescending } sortItem := &pages.GridSort{ diff --git a/mdl/executor/cmd_pages_builder_v3_layout.go b/mdl/executor/cmd_pages_builder_v3_layout.go index 44ebab6e..020bcc99 100644 --- a/mdl/executor/cmd_pages_builder_v3_layout.go +++ b/mdl/executor/cmd_pages_builder_v3_layout.go @@ -24,7 +24,7 @@ func (pb *pageBuilder) buildLayoutGridV3(w *ast.WidgetV3) (*pages.LayoutGrid, er // Build rows from children for _, child := range w.Children { - if strings.ToUpper(child.Type) == "row" { + if strings.ToLower(child.Type) == "row" { row, err := pb.buildLayoutGridRowV3(child) if err != nil { return nil, err @@ -46,7 +46,7 @@ func (pb *pageBuilder) buildLayoutGridRowV3(w *ast.WidgetV3) (*pages.LayoutGridR // Build columns from children for _, child := range w.Children { - if strings.ToUpper(child.Type) == "column" { + if strings.ToLower(child.Type) == "column" { col, err := pb.buildLayoutGridColumnV3(child) if err != nil { return nil, err @@ -228,7 +228,7 @@ func (pb *pageBuilder) buildTabContainerV3(w *ast.WidgetV3) (*pages.TabContainer // Build tab pages from children for _, child := range w.Children { - if strings.ToUpper(child.Type) == "tabpage" { + if strings.ToLower(child.Type) == "tabpage" { tp, err := pb.buildTabPageV3(child) if err != nil { return nil, err diff --git a/mdl/executor/cmd_pages_builder_v3_widgets.go b/mdl/executor/cmd_pages_builder_v3_widgets.go index 7dd0a9e5..5ad66063 100644 --- a/mdl/executor/cmd_pages_builder_v3_widgets.go +++ b/mdl/executor/cmd_pages_builder_v3_widgets.go @@ -108,7 +108,7 @@ func (pb *pageBuilder) buildDataGridV3(w *ast.WidgetV3) (*pages.CustomWidget, er var columns []backend.DataGridColumnSpec var headerWidgets []pages.Widget for _, child := range w.Children { - switch strings.ToUpper(child.Type) { + switch strings.ToLower(child.Type) { case "column": attr := child.GetAttribute() if attr == "" && child.Name != "" && len(child.Children) == 0 { @@ -687,7 +687,7 @@ func (pb *pageBuilder) buildNavigationListV3(w *ast.WidgetV3) (*pages.Navigation // Build items from children (ITEM widgets) for _, child := range w.Children { - if strings.ToUpper(child.Type) == "item" { + if strings.ToLower(child.Type) == "item" { item, err := pb.buildNavigationListItemV3(child) if err != nil { return nil, err diff --git a/mdl/executor/cmd_rest_clients.go b/mdl/executor/cmd_rest_clients.go index 550e7dbe..badb41da 100644 --- a/mdl/executor/cmd_rest_clients.go +++ b/mdl/executor/cmd_rest_clients.go @@ -146,7 +146,7 @@ func outputRestOperation(w io.Writer, op *model.RestClientOperation) { } fmt.Fprintf(w, " operation %s {\n", op.Name) - fmt.Fprintf(w, " Method: %s,\n", op.HttpMethod) + fmt.Fprintf(w, " Method: %s,\n", strings.ToLower(op.HttpMethod)) fmt.Fprintf(w, " Path: '%s',\n", op.Path) // Parameters: ($var: Type, ...) @@ -178,10 +178,10 @@ func outputRestOperation(w io.Writer, op *model.RestClientOperation) { // Body if op.BodyType != "" { - switch op.BodyType { + switch strings.ToLower(op.BodyType) { case "template": fmt.Fprintf(w, " Body: template '%s',\n", strings.ReplaceAll(op.BodyVariable, "'", "''")) - case "EXPORT_MAPPING": + case "export_mapping": if op.BodyVariable != "" && len(op.BodyMappings) > 0 { fmt.Fprintf(w, " Body: mapping %s {\n", op.BodyVariable) writeExportMappings(w, op.BodyMappings, 6) @@ -190,7 +190,7 @@ func outputRestOperation(w io.Writer, op *model.RestClientOperation) { fmt.Fprintf(w, " Body: mapping %s,\n", op.BodyVariable) } default: - fmt.Fprintf(w, " Body: %s from %s,\n", op.BodyType, op.BodyVariable) + fmt.Fprintf(w, " Body: %s from %s,\n", strings.ToLower(op.BodyType), op.BodyVariable) } } @@ -200,7 +200,7 @@ func outputRestOperation(w io.Writer, op *model.RestClientOperation) { } // Response - switch op.ResponseType { + switch strings.ToLower(op.ResponseType) { case "none": fmt.Fprintln(w, " Response: none") case "json": @@ -410,7 +410,7 @@ func buildRestClientOperation(opDef *ast.RestOperationDef) *model.RestClientOper // Convert body mapping (export direction: Left=jsonField, Right=entityAttr) if opDef.BodyMapping != nil { - op.BodyType = "EXPORT_MAPPING" + op.BodyType = "export_mapping" op.BodyVariable = opDef.BodyMapping.Entity.String() op.BodyMappings = convertMappingEntries(opDef.BodyMapping.Entries, false) } diff --git a/mdl/executor/cmd_settings.go b/mdl/executor/cmd_settings.go index d3beb021..b83cdfdb 100644 --- a/mdl/executor/cmd_settings.go +++ b/mdl/executor/cmd_settings.go @@ -178,7 +178,7 @@ func alterSettings(ctx *ExecContext, stmt *ast.AlterSettingsStmt) error { return mdlerrors.NewBackend("read project settings", err) } - section := strings.ToUpper(stmt.Section) + section := strings.ToLower(stmt.Section) switch section { case "model": if ps.Model == nil { @@ -212,7 +212,7 @@ func alterSettings(ctx *ExecContext, stmt *ast.AlterSettingsStmt) error { } } - case "LANGUAGE": + case "language": if ps.Language == nil { return mdlerrors.NewNotFound("settings section", "language") } diff --git a/mdl/executor/roundtrip_doctype_test.go b/mdl/executor/roundtrip_doctype_test.go index c4f753e1..d9ebfe73 100644 --- a/mdl/executor/roundtrip_doctype_test.go +++ b/mdl/executor/roundtrip_doctype_test.go @@ -30,6 +30,9 @@ var scriptModuleDeps = map[string][]string{ // These are syntax showcase scripts that intentionally omit entities, constants, // headers etc. that full validation requires. var scriptKnownCEErrors = map[string][]string{ + "03-page-examples.mdl": { + "CE3637", // Data view listen to gallery in sibling layout-grid column — Mendix scoping limitation + }, "02-microflow-examples.mdl": { "CE0117", // Expression error in LOG WARNING on Mendix 10.x (string concat syntax difference) }, diff --git a/mdl/executor/validate_page_context.go b/mdl/executor/validate_page_context.go index 36fe2d07..9d333c18 100644 --- a/mdl/executor/validate_page_context.go +++ b/mdl/executor/validate_page_context.go @@ -75,9 +75,9 @@ func walkWidgetsWithContext(widgets []*ast.WidgetV3, paramNames map[string]bool, } // Check if this widget type is a data container that sets context - widgetType := strings.ToUpper(w.Type) + widgetType := strings.ToLower(w.Type) switch widgetType { - case "dataview", "datagrid", "listview", "gallery", "TEMPLATEVIEW": + case "dataview", "datagrid", "listview", "gallery", "templateview": if ds == nil { // Data container without DataSource — context comes from enclosing container childHasContext = hasEntityContext diff --git a/mdl/executor/widget_engine.go b/mdl/executor/widget_engine.go index fb65d4fd..745ca781 100644 --- a/mdl/executor/widget_engine.go +++ b/mdl/executor/widget_engine.go @@ -496,8 +496,8 @@ func (e *PluggableWidgetEngine) applyChildSlots(builder backend.WidgetObjectBuil var defaultWidgets []pages.Widget for _, child := range w.Children { - upperType := strings.ToUpper(child.Type) - if slot, ok := slotContainers[upperType]; ok { + lowerType := strings.ToLower(child.Type) + if slot, ok := slotContainers[lowerType]; ok { for _, slotChild := range child.Children { widget, err := e.pageBuilder.buildWidgetV3(slotChild) if err != nil { diff --git a/mdl/visitor/visitor_businessevents.go b/mdl/visitor/visitor_businessevents.go index 02f68d44..af66af70 100644 --- a/mdl/visitor/visitor_businessevents.go +++ b/mdl/visitor/visitor_businessevents.go @@ -103,5 +103,14 @@ func dataTypeSimpleName(ctx parser.IDataTypeContext) string { if idx := strings.Index(text, "("); idx >= 0 { text = text[:idx] } + // Normalize to Mendix canonical casing (grammar is case-insensitive, Mendix BSON is not). + canonical := map[string]string{ + "string": "String", "integer": "Integer", "long": "Long", + "decimal": "Decimal", "boolean": "Boolean", "datetime": "DateTime", + "binary": "Binary", + } + if c, ok := canonical[strings.ToLower(text)]; ok { + return c + } return text } diff --git a/mdl/visitor/visitor_page_v3.go b/mdl/visitor/visitor_page_v3.go index 71fbf219..123b5829 100644 --- a/mdl/visitor/visitor_page_v3.go +++ b/mdl/visitor/visitor_page_v3.go @@ -1088,10 +1088,10 @@ func buildDesignPropertyEntryV3(ctx parser.IDesignPropertyEntryV3Context) *ast.D // Value: second STRING_LITERAL, ON, or OFF if entryCtx.ON() != nil { - return &ast.DesignPropertyEntryV3{Key: key, Value: "ON"} + return &ast.DesignPropertyEntryV3{Key: key, Value: "on"} } if entryCtx.OFF() != nil { - return &ast.DesignPropertyEntryV3{Key: key, Value: "OFF"} + return &ast.DesignPropertyEntryV3{Key: key, Value: "off"} } if len(allStrings) >= 2 { return &ast.DesignPropertyEntryV3{Key: key, Value: unquoteString(allStrings[1].GetText())} diff --git a/mdl/visitor/visitor_rest.go b/mdl/visitor/visitor_rest.go index c80ff1d9..d007060b 100644 --- a/mdl/visitor/visitor_rest.go +++ b/mdl/visitor/visitor_rest.go @@ -139,7 +139,7 @@ func parseRestClientOpProp(ctx *parser.RestClientOpPropContext, op *ast.RestOper // Method: GET if mCtx := ctx.RestHttpMethod(); mCtx != nil { - op.Method = strings.ToUpper(mCtx.GetText()) + op.Method = strings.ToLower(mCtx.GetText()) return } @@ -153,10 +153,10 @@ func parseRestClientOpProp(ctx *parser.RestClientOpPropContext, op *ast.RestOper } switch key { case "body": - op.BodyType = "MAPPING" + op.BodyType = "mapping" op.BodyMapping = md case "response": - op.ResponseType = "MAPPING" + op.ResponseType = "mapping" op.ResponseMapping = md } return @@ -165,7 +165,7 @@ func parseRestClientOpProp(ctx *parser.RestClientOpPropContext, op *ast.RestOper // TEMPLATE 'string' if ctx.TEMPLATE() != nil { if sl := ctx.STRING_LITERAL(); sl != nil { - op.BodyType = "TEMPLATE" + op.BodyType = "template" op.BodyVariable = unquoteString(sl.GetText()) } return @@ -177,21 +177,21 @@ func parseRestClientOpProp(ctx *parser.RestClientOpPropContext, op *ast.RestOper if ctx.FROM() != nil { // Body: JSON FROM $var, FILE FROM $var if ctx.JSON() != nil { - op.BodyType = "JSON" + op.BodyType = "json" } else if ctx.FILE_KW() != nil { - op.BodyType = "FILE" + op.BodyType = "file" } op.BodyVariable = varName } else if ctx.AS() != nil { // Response: JSON AS $var, STRING AS $var, etc. if ctx.JSON() != nil { - op.ResponseType = "JSON" + op.ResponseType = "json" } else if ctx.STRING_TYPE() != nil { - op.ResponseType = "STRING" + op.ResponseType = "string" } else if ctx.FILE_KW() != nil { - op.ResponseType = "FILE" + op.ResponseType = "file" } else if ctx.STATUS() != nil { - op.ResponseType = "STATUS" + op.ResponseType = "status" } op.ResponseVariable = varName } @@ -202,7 +202,7 @@ func parseRestClientOpProp(ctx *parser.RestClientOpPropContext, op *ast.RestOper if ctx.NONE() != nil { switch key { case "response": - op.ResponseType = "NONE" + op.ResponseType = "none" case "authentication": // handled at service level } diff --git a/mdl/visitor/visitor_settings.go b/mdl/visitor/visitor_settings.go index 0fb21800..b8354d82 100644 --- a/mdl/visitor/visitor_settings.go +++ b/mdl/visitor/visitor_settings.go @@ -17,7 +17,7 @@ func (b *Builder) ExitAlterSettingsClause(ctx *parser.AlterSettingsClauseContext if ctx.DROP() != nil && ctx.CONSTANT() != nil { // ALTER SETTINGS DROP CONSTANT 'name' [IN CONFIGURATION 'cfg'] - stmt.Section = "CONSTANT" + stmt.Section = "constant" stmt.DropConstant = true allStrings := ctx.AllSTRING_LITERAL() if len(allStrings) > 0 { @@ -28,7 +28,7 @@ func (b *Builder) ExitAlterSettingsClause(ctx *parser.AlterSettingsClauseContext } } else if ctx.CONSTANT() != nil { // ALTER SETTINGS CONSTANT 'name' (VALUE 'value' | DROP) [IN CONFIGURATION 'cfg'] - stmt.Section = "CONSTANT" + stmt.Section = "constant" allStrings := ctx.AllSTRING_LITERAL() if len(allStrings) > 0 { stmt.ConstantId = unquoteString(allStrings[0].GetText()) @@ -44,7 +44,7 @@ func (b *Builder) ExitAlterSettingsClause(ctx *parser.AlterSettingsClauseContext } } else if ctx.CONFIGURATION() != nil { // ALTER SETTINGS CONFIGURATION 'name' Key = Value, ... - stmt.Section = "CONFIGURATION" + stmt.Section = "configuration" allStrings := ctx.AllSTRING_LITERAL() if len(allStrings) > 0 { stmt.ConfigName = unquoteString(allStrings[0].GetText()) diff --git a/mdl/visitor/visitor_workflow.go b/mdl/visitor/visitor_workflow.go index fd309398..dbc56381 100644 --- a/mdl/visitor/visitor_workflow.go +++ b/mdl/visitor/visitor_workflow.go @@ -278,28 +278,28 @@ func buildWorkflowSetPropertyOp(ctx *parser.WorkflowSetPropertyContext) *ast.Set op := &ast.SetWorkflowPropertyOp{} if ctx.DISPLAY() != nil { - op.Property = "DISPLAY" + op.Property = "display" op.Value = unquoteString(ctx.STRING_LITERAL().GetText()) } else if ctx.DESCRIPTION() != nil { - op.Property = "DESCRIPTION" + op.Property = "description" op.Value = unquoteString(ctx.STRING_LITERAL().GetText()) } else if ctx.EXPORT() != nil { - op.Property = "EXPORT_LEVEL" + op.Property = "export_level" if ctx.API() != nil { op.Value = "API" } else if ctx.IDENTIFIER() != nil { op.Value = ctx.IDENTIFIER().GetText() } } else if ctx.DUE() != nil { - op.Property = "DUE_DATE" + op.Property = "due_date" op.Value = unquoteString(ctx.STRING_LITERAL().GetText()) } else if ctx.OVERVIEW() != nil { - op.Property = "OVERVIEW_PAGE" + op.Property = "overview_page" if qn := ctx.QualifiedName(); qn != nil { op.Entity = buildQualifiedName(qn) } } else if ctx.PARAMETER() != nil { - op.Property = "PARAMETER" + op.Property = "parameter" op.Value = ctx.VARIABLE().GetText() if qn := ctx.QualifiedName(); qn != nil { op.Entity = buildQualifiedName(qn) @@ -317,23 +317,23 @@ func buildActivitySetPropertyOp(ctx *parser.ActivitySetPropertyContext, ref stri } if ctx.PAGE() != nil { - op.Property = "PAGE" + op.Property = "page" if qn := ctx.QualifiedName(); qn != nil { op.PageName = buildQualifiedName(qn) } } else if ctx.DESCRIPTION() != nil { - op.Property = "DESCRIPTION" + op.Property = "description" op.Value = unquoteString(ctx.STRING_LITERAL().GetText()) } else if ctx.TARGETING() != nil && ctx.MICROFLOW() != nil { - op.Property = "TARGETING_MICROFLOW" + op.Property = "targeting_microflow" if qn := ctx.QualifiedName(); qn != nil { op.Microflow = buildQualifiedName(qn) } } else if ctx.TARGETING() != nil && ctx.XPATH() != nil { - op.Property = "TARGETING_XPATH" + op.Property = "targeting_xpath" op.Value = unquoteString(ctx.STRING_LITERAL().GetText()) } else if ctx.DUE() != nil { - op.Property = "DUE_DATE" + op.Property = "due_date" op.Value = unquoteString(ctx.STRING_LITERAL().GetText()) } diff --git a/mdl/visitor/visitor_workflow_test.go b/mdl/visitor/visitor_workflow_test.go index 39635374..bdc3ee91 100644 --- a/mdl/visitor/visitor_workflow_test.go +++ b/mdl/visitor/visitor_workflow_test.go @@ -612,7 +612,7 @@ func TestAlterWorkflow_SetDisplay(t *testing.T) { if !ok { t.Fatalf("Expected SetWorkflowPropertyOp, got %T", stmt.Operations[0]) } - if op.Property != "DISPLAY" { + if op.Property != "display" { t.Errorf("Expected Property 'DISPLAY', got %q", op.Property) } if op.Value != "New Display Name" { @@ -645,10 +645,10 @@ func TestAlterWorkflow_MultipleOperations(t *testing.T) { prop string value string }{ - {"DISPLAY", "Updated Approval"}, - {"DESCRIPTION", "Updated description"}, - {"EXPORT_LEVEL", "Hidden"}, - {"DUE_DATE", "PT48H"}, + {"display", "Updated Approval"}, + {"description", "Updated description"}, + {"export_level", "Hidden"}, + {"due_date", "PT48H"}, } for i, check := range checks { @@ -685,7 +685,7 @@ func TestAlterWorkflow_SetActivityPage(t *testing.T) { if !ok { t.Fatalf("Expected SetActivityPropertyOp, got %T", stmt.Operations[0]) } - if op.Property != "PAGE" { + if op.Property != "page" { t.Errorf("Expected Property 'PAGE', got %q", op.Property) } if op.ActivityRef != "Review" { @@ -716,7 +716,7 @@ func TestAlterWorkflow_SetActivityWithAtPosition(t *testing.T) { if op.AtPosition != 2 { t.Errorf("Expected AtPosition 2, got %d", op.AtPosition) } - if op.Property != "DESCRIPTION" { + if op.Property != "description" { t.Errorf("Expected Property 'DESCRIPTION', got %q", op.Property) } if op.Value != "Updated desc" { @@ -1002,7 +1002,7 @@ func TestAlterWorkflow_SetParameter(t *testing.T) { if !ok { t.Fatalf("Expected SetWorkflowPropertyOp, got %T", stmt.Operations[0]) } - if op.Property != "PARAMETER" { + if op.Property != "parameter" { t.Errorf("Expected Property 'PARAMETER', got %q", op.Property) } if op.Value != "$ctx" { @@ -1029,7 +1029,7 @@ func TestAlterWorkflow_SetOverviewPage(t *testing.T) { if !ok { t.Fatalf("Expected SetWorkflowPropertyOp, got %T", stmt.Operations[0]) } - if op.Property != "OVERVIEW_PAGE" { + if op.Property != "overview_page" { t.Errorf("Expected Property 'OVERVIEW_PAGE', got %q", op.Property) } if op.Entity.Module != "M" || op.Entity.Name != "AdminPage" { @@ -1056,7 +1056,7 @@ func TestAlterWorkflow_SetActivityTargeting(t *testing.T) { } mfOp := stmt.Operations[0].(*ast.SetActivityPropertyOp) - if mfOp.Property != "TARGETING_MICROFLOW" { + if mfOp.Property != "targeting_microflow" { t.Errorf("Expected Property 'TARGETING_MICROFLOW', got %q", mfOp.Property) } if mfOp.Microflow.Name != "GetReviewers" { @@ -1064,7 +1064,7 @@ func TestAlterWorkflow_SetActivityTargeting(t *testing.T) { } xpOp := stmt.Operations[1].(*ast.SetActivityPropertyOp) - if xpOp.Property != "TARGETING_XPATH" { + if xpOp.Property != "targeting_xpath" { t.Errorf("Expected Property 'TARGETING_XPATH', got %q", xpOp.Property) } if xpOp.Value != "[Role = 'Manager']" { @@ -1085,7 +1085,7 @@ func TestAlterWorkflow_SetActivityDueDate(t *testing.T) { stmt := prog.Statements[0].(*ast.AlterWorkflowStmt) op := stmt.Operations[0].(*ast.SetActivityPropertyOp) - if op.Property != "DUE_DATE" { + if op.Property != "due_date" { t.Errorf("Expected Property 'DUE_DATE', got %q", op.Property) } if op.Value != "PT72H" { diff --git a/sdk/workflows/workflow.go b/sdk/workflows/workflow.go index e0c92e4a..b1e20c06 100644 --- a/sdk/workflows/workflow.go +++ b/sdk/workflows/workflow.go @@ -270,9 +270,9 @@ type BooleanConditionOutcome struct { // GetName returns a display name for the outcome. func (o *BooleanConditionOutcome) GetName() string { if o.Value { - return "TRUE" + return "true" } - return "FALSE" + return "false" } // GetFlow returns the flow for this outcome.