mxrb 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/mxrb +458 -10
- data/docs/de-DE/README.md +1 -0
- data/docs/de-DE/oql-sql.md +42 -0
- data/docs/de-DE/project-structure.md +201 -2
- data/docs/de-DE/runtime-ruby.md +104 -0
- data/docs/de-DE/runtime-schema-migrations.md +44 -0
- data/docs/de-DE/validation-matrix.md +42 -4
- data/docs/en-US/README.md +1 -0
- data/docs/en-US/oql-sql.md +41 -0
- data/docs/en-US/project-structure.md +192 -2
- data/docs/en-US/runtime-ruby.md +100 -0
- data/docs/en-US/runtime-schema-migrations.md +41 -0
- data/docs/en-US/validation-matrix.md +39 -4
- data/docs/pt-BR/README.md +1 -0
- data/docs/pt-BR/entity-dsl.md +8 -0
- data/docs/pt-BR/oql-sql.md +41 -0
- data/docs/pt-BR/project-structure.md +197 -2
- data/docs/pt-BR/runtime-ruby.md +108 -0
- data/docs/pt-BR/runtime-schema-migrations.md +40 -0
- data/docs/pt-BR/validation-matrix.md +42 -5
- data/docs/pt-BR/writing.md +28 -0
- data/lib/mxrb/cli/help.rb +426 -0
- data/lib/mxrb/cli/release.rb +137 -0
- data/lib/mxrb/compiler/compatibility_analyzer.rb +1 -1
- data/lib/mxrb/compiler/data_grid_bundle_compiler.rb +8 -1
- data/lib/mxrb/compiler/domain_document_compiler.rb +3 -0
- data/lib/mxrb/compiler/gallery_bundle_compiler.rb +11 -1
- data/lib/mxrb/compiler/generic_widget_bundle_compiler.rb +76 -19
- data/lib/mxrb/compiler/legacy_custom_widget_compiler.rb +159 -0
- data/lib/mxrb/compiler/legacy_data_grid_compiler.rb +43 -7
- data/lib/mxrb/compiler/legacy_page_builder.rb +1248 -23
- data/lib/mxrb/compiler/packager.rb +27 -13
- data/lib/mxrb/compiler/page_bundle_compiler.rb +13 -4
- data/lib/mxrb/compiler/portable_packager.rb +16 -11
- data/lib/mxrb/compiler/web_bundle_builder.rb +5 -1
- data/lib/mxrb/compiler/web_shell_materializer.rb +42 -2
- data/lib/mxrb/compiler/widget_package_extractor.rb +3 -0
- data/lib/mxrb/domain_diagram/lifecycle.rb +272 -0
- data/lib/mxrb/domain_diagram.rb +409 -0
- data/lib/mxrb/dsl/builder.rb +62 -11
- data/lib/mxrb/environment.rb +226 -0
- data/lib/mxrb/exporter.rb +265 -45
- data/lib/mxrb/http/server.rb +107 -0
- data/lib/mxrb/initializer.rb +80 -9
- data/lib/mxrb/integrity/validator.rb +32 -7
- data/lib/mxrb/io/bson_codec.rb +42 -1
- data/lib/mxrb/io/mpr_file.rb +146 -3
- data/lib/mxrb/model/attribute.rb +3 -0
- data/lib/mxrb/model/entity.rb +44 -2
- data/lib/mxrb/model/microflow.rb +3 -1
- data/lib/mxrb/model/module.rb +71 -0
- data/lib/mxrb/model/page.rb +126 -15
- data/lib/mxrb/model/project.rb +3 -0
- data/lib/mxrb/modeler/catalog.rb +178 -0
- data/lib/mxrb/official_marketplace/module_package_importer.rb +23 -12
- data/lib/mxrb/official_marketplace/widget_package_installer.rb +15 -11
- data/lib/mxrb/official_marketplace.rb +9 -3
- data/lib/mxrb/oql/reverse_translator.rb +394 -0
- data/lib/mxrb/oql/server.rb +4 -8
- data/lib/mxrb/oql.rb +32 -4
- data/lib/mxrb/progress.rb +242 -0
- data/lib/mxrb/project_lifecycle.rb +5 -2
- data/lib/mxrb/ruby_app/exporter.rb +1749 -0
- data/lib/mxrb/ruby_app/preset.rb +506 -0
- data/lib/mxrb/ruby_app/session_manager.rb +122 -0
- data/lib/mxrb/ruby_app.rb +1361 -0
- data/lib/mxrb/runtime/access_control.rb +408 -0
- data/lib/mxrb/runtime/native.rb +1015 -93
- data/lib/mxrb/runtime/scheduler.rb +396 -0
- data/lib/mxrb/runtime/schema_migrator.rb +598 -0
- data/lib/mxrb/runtime/shared_store.rb +335 -0
- data/lib/mxrb/runtime/sqlite_store.rb +729 -0
- data/lib/mxrb/scaffold/generator.rb +11 -3
- data/lib/mxrb/team_server.rb +10 -7
- data/lib/mxrb/uml/activity_diagram.rb +118 -0
- data/lib/mxrb/uml/class_diagram.rb +118 -0
- data/lib/mxrb/uml/sequence_diagram.rb +112 -0
- data/lib/mxrb/uml/server.rb +146 -0
- data/lib/mxrb/uml/support.rb +35 -0
- data/lib/mxrb/version.rb +1 -1
- data/lib/mxrb/web_ui/assets/abnfDiagram-N423BO3Z-C4JD3cEC.js +1 -0
- data/lib/mxrb/web_ui/assets/arc-3Z53kgFp.js +1 -0
- data/lib/mxrb/web_ui/assets/architecture-TIHT7OUA-BStBTLea.js +1 -0
- data/lib/mxrb/web_ui/assets/architectureDiagram-T3A2C74G-DBwqnM4J.js +36 -0
- data/lib/mxrb/web_ui/assets/array-BifhSqXX.js +1 -0
- data/lib/mxrb/web_ui/assets/blockDiagram-VBNYF7ZC-DLtuHt-j.js +132 -0
- data/lib/mxrb/web_ui/assets/c4Diagram-5PPSVZJV-ConSk_pe.js +10 -0
- data/lib/mxrb/web_ui/assets/channel-BhPvD7Dt.js +1 -0
- data/lib/mxrb/web_ui/assets/chunk-2GRJ4B5K-D2HpWsf_.js +1 -0
- data/lib/mxrb/web_ui/assets/chunk-2Q5K7J3B-C1jixKkw.js +1 -0
- data/lib/mxrb/web_ui/assets/chunk-4I5QYGJK-CiIdNwaF.js +1 -0
- data/lib/mxrb/web_ui/assets/chunk-5RXB4S5H-Bu_AaEkE.js +231 -0
- data/lib/mxrb/web_ui/assets/chunk-5VM5RSS4-ZNzvKenW.js +15 -0
- data/lib/mxrb/web_ui/assets/chunk-6Q2QTUOP-wQkNmt_X.js +88 -0
- data/lib/mxrb/web_ui/assets/chunk-7BUUIJ7U-Bb538aSH.js +1 -0
- data/lib/mxrb/web_ui/assets/chunk-GF5L2VYU-G8MmiBzU.js +206 -0
- data/lib/mxrb/web_ui/assets/chunk-I66GZJ75-CulcrLPh.js +127 -0
- data/lib/mxrb/web_ui/assets/chunk-JQJVKLGR-ukjzcdlL.js +156 -0
- data/lib/mxrb/web_ui/assets/chunk-JWPE2WC7-DVXcaiue.js +1 -0
- data/lib/mxrb/web_ui/assets/chunk-KBJHAD2P-Wm35lYov.js +1 -0
- data/lib/mxrb/web_ui/assets/chunk-KEIR6QF5-BICK3FdT.js +161 -0
- data/lib/mxrb/web_ui/assets/chunk-NSK5VX7P-D2nYrCY4.js +2 -0
- data/lib/mxrb/web_ui/assets/chunk-QR6OTTB3-BrdIzg4Q.js +62 -0
- data/lib/mxrb/web_ui/assets/chunk-RYQCIY6F-CCfZMcW6.js +1 -0
- data/lib/mxrb/web_ui/assets/chunk-UBXNYLIW-BPEVYsFK.js +1 -0
- data/lib/mxrb/web_ui/assets/chunk-W5SLKNZC-2E6OPhA4.js +1 -0
- data/lib/mxrb/web_ui/assets/chunk-WRU74C26-CBIvOyWp.js +70 -0
- data/lib/mxrb/web_ui/assets/chunk-XXDRQBXY-pH58XAyl.js +1 -0
- data/lib/mxrb/web_ui/assets/chunk-Y2CYZVJY-DsF7k-Jl.js +1 -0
- data/lib/mxrb/web_ui/assets/classDiagram-JCYQIIEL-xiqo4D89.js +1 -0
- data/lib/mxrb/web_ui/assets/classDiagram-v2-OCEON4UE-xiqo4D89.js +1 -0
- data/lib/mxrb/web_ui/assets/cose-bilkent-JH36ORCC-t_flPpii.js +1 -0
- data/lib/mxrb/web_ui/assets/cynefin-VYW2F7L2-BIqktTEv.js +1 -0
- data/lib/mxrb/web_ui/assets/cynefinDiagram-MW4NZA55-C2d--lut.js +62 -0
- data/lib/mxrb/web_ui/assets/cytoscape.esm-B-NFISlW.js +321 -0
- data/lib/mxrb/web_ui/assets/dagre-Buvkdvvj.js +1 -0
- data/lib/mxrb/web_ui/assets/dagre-VZM6K2ZE-CSz2_tb5.js +4 -0
- data/lib/mxrb/web_ui/assets/defaultLocale-BFoDCU3G.js +1 -0
- data/lib/mxrb/web_ui/assets/diagram-7IWD3JNH-DCt7u7V_.js +30 -0
- data/lib/mxrb/web_ui/assets/diagram-B4RE2ZJO-DqZBqkMu.js +3 -0
- data/lib/mxrb/web_ui/assets/diagram-LBJQPF4R-ClIYbIsI.js +24 -0
- data/lib/mxrb/web_ui/assets/diagram-Q27KOJAE-DFxhvthJ.js +24 -0
- data/lib/mxrb/web_ui/assets/diagram-UB23O5K3-BSUTXptv.js +41 -0
- data/lib/mxrb/web_ui/assets/dist-D2qOEbeJ.js +1 -0
- data/lib/mxrb/web_ui/assets/domain-mGOZ1KCG.css +1 -0
- data/lib/mxrb/web_ui/assets/domain-qsjXhy4v.js +1 -0
- data/lib/mxrb/web_ui/assets/ebnfDiagram-BXEA7PRR-B5reICEi.js +1 -0
- data/lib/mxrb/web_ui/assets/erDiagram-JOGREHBK-Co5Mxn2p.js +85 -0
- data/lib/mxrb/web_ui/assets/eventmodeling-45OFAUF4-C1ylhSks.js +1 -0
- data/lib/mxrb/web_ui/assets/flowDiagram-UKHOOZJN-CHXaJIaS.js +1 -0
- data/lib/mxrb/web_ui/assets/ganttDiagram-PKOTCBZU-DPPPaWaz.js +292 -0
- data/lib/mxrb/web_ui/assets/gitGraph-TEB2WS4Q-qS77ywA9.js +1 -0
- data/lib/mxrb/web_ui/assets/gitGraphDiagram-DS77QQ5N-DpAv6-BT.js +106 -0
- data/lib/mxrb/web_ui/assets/graphlib-DS17s2tU.js +1 -0
- data/lib/mxrb/web_ui/assets/info-DKCQHKI2-C9VD1Y4e.js +1 -0
- data/lib/mxrb/web_ui/assets/infoDiagram-6WML65LV-Bk1kbcCy.js +2 -0
- data/lib/mxrb/web_ui/assets/init-C-OQMol4.js +1 -0
- data/lib/mxrb/web_ui/assets/ishikawaDiagram-WSZJBQD7-0gcISBFR.js +70 -0
- data/lib/mxrb/web_ui/assets/journeyDiagram-NVQOT4AX-Dt0RQnlh.js +139 -0
- data/lib/mxrb/web_ui/assets/jsx-runtime-DV0a5kSb.js +9 -0
- data/lib/mxrb/web_ui/assets/kanban-definition-27J2QSJJ-DIPQM7w9.js +89 -0
- data/lib/mxrb/web_ui/assets/katex-CXMH3UgJ.js +257 -0
- data/lib/mxrb/web_ui/assets/line-C0rYD-tL.js +1 -0
- data/lib/mxrb/web_ui/assets/linear-BPPxWorj.js +1 -0
- data/lib/mxrb/web_ui/assets/map-BaFkSB1l.js +1 -0
- data/lib/mxrb/web_ui/assets/mermaid-parser.core-B_UPzTxa.js +7 -0
- data/lib/mxrb/web_ui/assets/mindmap-definition-FAOFIHXS-CdJRSMuk.js +96 -0
- data/lib/mxrb/web_ui/assets/modeler-BNqHthwk.css +1 -0
- data/lib/mxrb/web_ui/assets/modeler-CQmqflbg.js +1 -0
- data/lib/mxrb/web_ui/assets/ordinal-BDEzSJ7C.js +1 -0
- data/lib/mxrb/web_ui/assets/packet-7NZHBO7P-CwQ4NSBs.js +1 -0
- data/lib/mxrb/web_ui/assets/path-fybaL0A-.js +1 -0
- data/lib/mxrb/web_ui/assets/pegDiagram-VL7TDLO6-D40S7ppx.js +1 -0
- data/lib/mxrb/web_ui/assets/pie-RZYD4A2V-CJroHMKh.js +1 -0
- data/lib/mxrb/web_ui/assets/pieDiagram-7S7Q4E2Y-QB54__BV.js +39 -0
- data/lib/mxrb/web_ui/assets/quadrantDiagram-CIZ2JOQS-DBhDS6ag.js +7 -0
- data/lib/mxrb/web_ui/assets/radar-I7S5WNFK-DdIUwd2d.js +1 -0
- data/lib/mxrb/web_ui/assets/railroad-3IZDKUUU-B1Lw6Xyq.js +1 -0
- data/lib/mxrb/web_ui/assets/railroad-abnf-AHOZXSZD-CQgQoeak.js +1 -0
- data/lib/mxrb/web_ui/assets/railroad-ebnf-EBAXGLYW-D7qEQ2x8.js +1 -0
- data/lib/mxrb/web_ui/assets/railroad-peg-LSFZ7HO6-C005Vxbb.js +1 -0
- data/lib/mxrb/web_ui/assets/railroadDiagram-AXF67PYL-BBP2qk7M.js +1 -0
- data/lib/mxrb/web_ui/assets/requirementDiagram-LRYGKXZP-D2cLsAoI.js +84 -0
- data/lib/mxrb/web_ui/assets/rough.esm-Dy-Kn_BL.js +1 -0
- data/lib/mxrb/web_ui/assets/sankeyDiagram-W5VNT64P-Bpi3FiP2.js +40 -0
- data/lib/mxrb/web_ui/assets/sequenceDiagram-SI44F4Z6-DCRcDlVe.js +162 -0
- data/lib/mxrb/web_ui/assets/sizeCapture-X5ZJPWSS-B0uUizjq.js +1 -0
- data/lib/mxrb/web_ui/assets/src-CvxfUak2.js +1 -0
- data/lib/mxrb/web_ui/assets/stateDiagram-OKZ733FA-C2GCEoxl.js +1 -0
- data/lib/mxrb/web_ui/assets/stateDiagram-v2-UEYNNEHI-D2gWgedh.js +1 -0
- data/lib/mxrb/web_ui/assets/swimlanes-SLNWSIFB-CRI9irEW.js +2 -0
- data/lib/mxrb/web_ui/assets/swimlanesDiagram-ULZ7WXOC-C5Wb_-hZ.js +8 -0
- data/lib/mxrb/web_ui/assets/theme-_mxc7BdY.css +1 -0
- data/lib/mxrb/web_ui/assets/timeline-definition-Z64GVDOM-B1-mNg-h.js +120 -0
- data/lib/mxrb/web_ui/assets/treeView-QDETBFTQ-7CTvIwKq.js +1 -0
- data/lib/mxrb/web_ui/assets/treemap-6X3UGDF4-CtL22pq5.js +1 -0
- data/lib/mxrb/web_ui/assets/uml-C3KAFGTq.js +51 -0
- data/lib/mxrb/web_ui/assets/uml-Dn-qd01X.css +1 -0
- data/lib/mxrb/web_ui/assets/vennDiagram-T6HMQDX7-BzVnUEAy.js +34 -0
- data/lib/mxrb/web_ui/assets/wardley-OPB4EBWU-JNi-QNag.js +1 -0
- data/lib/mxrb/web_ui/assets/wardleyDiagram-T6FBY63Y-BUwmAQ-B.js +78 -0
- data/lib/mxrb/web_ui/assets/xychartDiagram-ELKLHX3M-DEQS8sKp.js +7 -0
- data/lib/mxrb/web_ui/domain.html +15 -0
- data/lib/mxrb/web_ui/modeler.html +16 -0
- data/lib/mxrb/web_ui/uml.html +31 -0
- data/lib/mxrb/web_ui.rb +89 -0
- data/lib/mxrb/widget_certification.rb +208 -0
- data/lib/mxrb/writer.rb +278 -41
- data/lib/mxrb.rb +38 -8
- metadata +157 -5
data/lib/mxrb/writer.rb
CHANGED
|
@@ -31,24 +31,55 @@ module Mxrb
|
|
|
31
31
|
def initialize(path, definition)
|
|
32
32
|
@path = File.expand_path(path)
|
|
33
33
|
@definition = definition
|
|
34
|
+
@progress = Progress::NullTask.instance
|
|
34
35
|
end
|
|
35
36
|
|
|
36
37
|
def write!
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
38
|
+
mpr = nil
|
|
39
|
+
native_units = prepared_native_units
|
|
40
|
+
asset_manifest = project_asset_manifest
|
|
41
|
+
total = 4 + native_units.count { _1["containment"] != "Modules" } +
|
|
42
|
+
@definition.fetch(:modules).size + Array(asset_manifest&.fetch("files", [])).size
|
|
43
|
+
Progress.with("Generating #{File.basename(@path)}", total:) do |progress|
|
|
44
|
+
@progress = progress
|
|
45
|
+
create_project! unless File.exist?(@path)
|
|
46
|
+
progress.advance(detail: "project container")
|
|
47
|
+
mpr = IO::MprFile.open(@path)
|
|
48
|
+
mpr.transaction do
|
|
49
|
+
apply(mpr, native_units)
|
|
50
|
+
write_native_compatibility(mpr, native_units)
|
|
51
|
+
mpr.write_architecture_definition(@definition)
|
|
52
|
+
mpr.write_ruby_app_sources(ruby_app_source_files) if @definition[:ruby_app_sources_path]
|
|
53
|
+
end
|
|
54
|
+
progress.advance(detail: "model transaction")
|
|
55
|
+
materialize_project_assets(asset_manifest)
|
|
56
|
+
materialize_design_system
|
|
57
|
+
progress.advance(detail: "design system")
|
|
58
|
+
end
|
|
45
59
|
self
|
|
46
60
|
ensure
|
|
61
|
+
@progress = Progress::NullTask.instance
|
|
47
62
|
mpr&.close
|
|
48
63
|
end
|
|
49
64
|
|
|
50
65
|
private
|
|
51
66
|
|
|
67
|
+
def ruby_app_source_files
|
|
68
|
+
path = @definition.fetch(:ruby_app_sources_path)
|
|
69
|
+
manifest = JSON.parse(File.read(path))
|
|
70
|
+
manifest.fetch("files").map do |file|
|
|
71
|
+
relative = safe_asset_path(file.fetch("path"))
|
|
72
|
+
contents = Base64.strict_decode64(file.fetch("contents"))
|
|
73
|
+
checksum = Digest::SHA256.hexdigest(contents)
|
|
74
|
+
raise SerializationError, "Ruby source checksum mismatch: #{relative}" \
|
|
75
|
+
unless checksum == file.fetch("sha256")
|
|
76
|
+
|
|
77
|
+
{ path: relative, contents:, sha256: checksum, mode: file.fetch("mode", 0o644) }
|
|
78
|
+
end
|
|
79
|
+
rescue JSON::ParserError, KeyError, ArgumentError => e
|
|
80
|
+
raise SerializationError, "invalid Ruby source manifest: #{e.message}"
|
|
81
|
+
end
|
|
82
|
+
|
|
52
83
|
def materialize_design_system
|
|
53
84
|
design_system = @definition[:design_system]
|
|
54
85
|
return unless design_system
|
|
@@ -56,11 +87,17 @@ module Mxrb
|
|
|
56
87
|
Model::DesignMaterializer.new(File.dirname(@path), design_system).materialize!
|
|
57
88
|
end
|
|
58
89
|
|
|
59
|
-
def
|
|
90
|
+
def project_asset_manifest
|
|
60
91
|
assets = @definition[:project_assets]
|
|
61
92
|
return unless assets
|
|
62
93
|
|
|
63
|
-
|
|
94
|
+
JSON.parse(File.read(assets.fetch(:manifest)))
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def materialize_project_assets(manifest)
|
|
98
|
+
assets = @definition[:project_assets]
|
|
99
|
+
return unless assets && manifest
|
|
100
|
+
|
|
64
101
|
source_root = File.realpath(assets.fetch(:root))
|
|
65
102
|
target_root = File.dirname(@path)
|
|
66
103
|
manifest.fetch("files").each do |entry|
|
|
@@ -79,6 +116,7 @@ module Mxrb
|
|
|
79
116
|
FileUtils.mv(temporary, target)
|
|
80
117
|
ensure
|
|
81
118
|
FileUtils.rm_f(temporary) if temporary
|
|
119
|
+
@progress.advance(detail: "asset #{relative}") if defined?(relative) && relative
|
|
82
120
|
end
|
|
83
121
|
end
|
|
84
122
|
|
|
@@ -161,7 +199,7 @@ module Mxrb
|
|
|
161
199
|
JSON.parse(File.read(path))["format_version"]
|
|
162
200
|
end
|
|
163
201
|
|
|
164
|
-
def apply(mpr)
|
|
202
|
+
def apply(mpr, native_units)
|
|
165
203
|
root = mpr.root_unit
|
|
166
204
|
root_id = root.fetch("UnitID")
|
|
167
205
|
root_doc = mpr.parse_contents(root)
|
|
@@ -171,10 +209,6 @@ module Mxrb
|
|
|
171
209
|
"IsSystemProject" => false
|
|
172
210
|
}
|
|
173
211
|
mpr.update_unit(root_id, root_doc)
|
|
174
|
-
native_units = load_native_units(@definition[:native_units_path])
|
|
175
|
-
native_units = apply_native_unit_overrides(
|
|
176
|
-
native_units, @definition.fetch(:native_unit_overrides, [])
|
|
177
|
-
)
|
|
178
212
|
apply_native_project_units(mpr, root_id, native_units)
|
|
179
213
|
apply_default_project_units(mpr, root_id)
|
|
180
214
|
ensure_project_documents(mpr, root_id)
|
|
@@ -194,9 +228,18 @@ module Mxrb
|
|
|
194
228
|
write_module_security(mpr, module_id, mod) if mod.key?(:module_roles)
|
|
195
229
|
write_domain_model(mpr, module_id, mod)
|
|
196
230
|
write_documents(mpr, module_id, mod)
|
|
231
|
+
@progress.advance(detail: "module #{mod.fetch(:name)}")
|
|
197
232
|
end
|
|
198
233
|
write_project_security(mpr, root_id, @definition[:security]) if @definition[:security]
|
|
199
234
|
write_project_navigation(mpr, root_id, @definition[:navigation]) if @definition[:navigation]
|
|
235
|
+
@progress.advance(detail: "project security and navigation")
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
def prepared_native_units
|
|
239
|
+
apply_native_unit_overrides(
|
|
240
|
+
load_native_units(@definition[:native_units_path]),
|
|
241
|
+
@definition.fetch(:native_unit_overrides, [])
|
|
242
|
+
)
|
|
200
243
|
end
|
|
201
244
|
|
|
202
245
|
def load_native_units(path)
|
|
@@ -323,8 +366,21 @@ module Mxrb
|
|
|
323
366
|
mod.fetch(:native_documents, []).each do |document|
|
|
324
367
|
doc = document.fetch(:doc)
|
|
325
368
|
doc = legacy_layout_doc(doc) if doc['$Type'] == 'Forms$Layout' && legacy_layout?
|
|
369
|
+
existing = mpr.unit(document[:unit_id]) if document[:unit_id]
|
|
370
|
+
if existing
|
|
371
|
+
current = mpr.parse_contents(existing)
|
|
372
|
+
preserved = current.merge(doc).merge(
|
|
373
|
+
'$ID' => current['$ID'] || existing.fetch('UnitID'),
|
|
374
|
+
'$Type' => doc['$Type'] || doc[:'$Type'] || document.fetch(:type)
|
|
375
|
+
)
|
|
376
|
+
mpr.update_unit(existing.fetch('UnitID'), preserved)
|
|
377
|
+
next
|
|
378
|
+
end
|
|
379
|
+
|
|
380
|
+
requested_container = document[:container_id]
|
|
381
|
+
target_container = requested_container && mpr.unit(requested_container) ? requested_container : module_id
|
|
326
382
|
upsert_native_unit(
|
|
327
|
-
mpr,
|
|
383
|
+
mpr, target_container,
|
|
328
384
|
'containment' => document.fetch(:containment), 'doc' => doc
|
|
329
385
|
)
|
|
330
386
|
end
|
|
@@ -365,7 +421,10 @@ module Mxrb
|
|
|
365
421
|
|
|
366
422
|
def apply_native_unit_tree(mpr, target_root_id, units)
|
|
367
423
|
if units.any? { _1["unit_id"].to_s.empty? || _1["container_id"].to_s.empty? }
|
|
368
|
-
units.each
|
|
424
|
+
units.each do |unit|
|
|
425
|
+
upsert_native_unit(mpr, target_root_id, unit)
|
|
426
|
+
@progress.advance(detail: "native unit #{unit['name']}")
|
|
427
|
+
end
|
|
369
428
|
return
|
|
370
429
|
end
|
|
371
430
|
|
|
@@ -382,6 +441,7 @@ module Mxrb
|
|
|
382
441
|
target_container = mapped_containers.fetch(unit.fetch("container_id"))
|
|
383
442
|
actual_id = upsert_native_unit(mpr, target_container, unit)
|
|
384
443
|
mapped_containers[unit.fetch("unit_id")] = actual_id
|
|
444
|
+
@progress.advance(detail: "native unit #{unit['name']}")
|
|
385
445
|
end
|
|
386
446
|
pending = blocked
|
|
387
447
|
end
|
|
@@ -390,26 +450,59 @@ module Mxrb
|
|
|
390
450
|
def upsert_native_unit(mpr, container_id, unit)
|
|
391
451
|
doc = unit.fetch("doc")
|
|
392
452
|
name = doc["Name"] || doc["name"]
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
453
|
+
requested_id = unit["unit_id"].to_s
|
|
454
|
+
requested_id = nil if requested_id.empty?
|
|
455
|
+
stable = mpr.unit(requested_id) if requested_id
|
|
456
|
+
existing = stable if stable && mpr.parse_contents(stable)["$Type"] == doc["$Type"]
|
|
457
|
+
candidates = mpr.children_of(container_id)
|
|
458
|
+
existing ||= if name.to_s.empty?
|
|
459
|
+
candidates.find { mpr.parse_contents(_1)["$Type"] == doc["$Type"] }
|
|
460
|
+
else
|
|
461
|
+
candidates.find do |raw|
|
|
462
|
+
existing_doc = mpr.parse_contents(raw)
|
|
463
|
+
(existing_doc["Name"] || existing_doc["name"]) == name &&
|
|
464
|
+
existing_doc["$Type"] == doc["$Type"]
|
|
465
|
+
end
|
|
466
|
+
end
|
|
401
467
|
if existing
|
|
402
468
|
current = mpr.parse_contents(existing)
|
|
403
469
|
preserved = {
|
|
404
470
|
"$ID" => current["$ID"] || existing.fetch("UnitID"),
|
|
405
471
|
"$Type" => doc["$Type"]
|
|
406
472
|
}.merge(current).merge(doc)
|
|
473
|
+
preserved["$ID"] = current["$ID"] || existing.fetch("UnitID") unless existing.equal?(stable)
|
|
407
474
|
mpr.update_unit(existing.fetch("UnitID"), preserved)
|
|
408
475
|
existing.fetch("UnitID")
|
|
409
476
|
else
|
|
410
477
|
containment = unit.fetch("containment")
|
|
411
|
-
|
|
478
|
+
inserted_id = stable ? SecureRandom.uuid : requested_id
|
|
479
|
+
inserted_doc = stable ? doc.merge("$ID" => inserted_id) : doc
|
|
480
|
+
mpr.insert_unit(
|
|
481
|
+
container_uuid: container_id,
|
|
482
|
+
containment_name: containment,
|
|
483
|
+
contents_doc: inserted_doc,
|
|
484
|
+
unit_uuid: inserted_id
|
|
485
|
+
)
|
|
486
|
+
end
|
|
487
|
+
end
|
|
488
|
+
|
|
489
|
+
def write_native_compatibility(mpr, native_units)
|
|
490
|
+
mismatches = native_units.filter_map do |unit|
|
|
491
|
+
unit_id = unit["unit_id"].to_s
|
|
492
|
+
doc = unit.fetch("doc")
|
|
493
|
+
content_id = IO::BsonCodec.extract_id(doc["$ID"]).to_s
|
|
494
|
+
next if unit_id.empty? || content_id.empty? || unit_id == content_id
|
|
495
|
+
|
|
496
|
+
raw = mpr.unit(unit_id)
|
|
497
|
+
next unless raw
|
|
498
|
+
|
|
499
|
+
written = mpr.parse_contents(raw)
|
|
500
|
+
written_id = IO::BsonCodec.extract_id(written["$ID"]).to_s
|
|
501
|
+
next unless written_id == content_id && written["$Type"] == doc["$Type"]
|
|
502
|
+
|
|
503
|
+
{ unit_id: unit_id, content_id: content_id, type: doc["$Type"] }
|
|
412
504
|
end
|
|
505
|
+
mpr.write_legacy_unit_identity_mismatches(mismatches)
|
|
413
506
|
end
|
|
414
507
|
|
|
415
508
|
def write_project_security(mpr, root_id, security)
|
|
@@ -858,6 +951,7 @@ module Mxrb
|
|
|
858
951
|
doc.delete("__mxrb_preserve_native_body")
|
|
859
952
|
doc.delete("__mxrb_deep_structure_declared")
|
|
860
953
|
doc.delete("__mxrb_allow_concurrent_execution_declared")
|
|
954
|
+
doc.delete("__mxrb_apply_entity_access_declared")
|
|
861
955
|
doc.delete("__mxrb_mark_as_used_declared")
|
|
862
956
|
doc.delete("__mxrb_excluded_declared")
|
|
863
957
|
strip_nested_internal_keys(doc)
|
|
@@ -894,15 +988,61 @@ module Mxrb
|
|
|
894
988
|
def configure_pluggable_widget!(widget, options)
|
|
895
989
|
properties = custom_widget_properties(widget)
|
|
896
990
|
options.fetch(:properties, {}).each do |key, configured|
|
|
897
|
-
|
|
898
|
-
|
|
991
|
+
property = properties[key.to_s]
|
|
992
|
+
configure_custom_widget_value!(property, configured) if property
|
|
993
|
+
end
|
|
994
|
+
end
|
|
995
|
+
|
|
996
|
+
def configure_custom_widget_value!(property, configured)
|
|
997
|
+
value = property.fetch('Value')
|
|
998
|
+
unless configured.is_a?(Hash)
|
|
999
|
+
value['PrimitiveValue'] = configured.to_s unless configured.nil?
|
|
1000
|
+
return value
|
|
1001
|
+
end
|
|
1002
|
+
return value.merge!(stringify_keys(configured)) unless semantic_widget_value?(configured)
|
|
1003
|
+
|
|
1004
|
+
configured = configured.to_h { |key, item| [key.to_sym, item] }
|
|
1005
|
+
value['PrimitiveValue'] = configured[:primitive].to_s if configured.key?(:primitive)
|
|
1006
|
+
value['Expression'] = configured[:expression].to_s if configured.key?(:expression)
|
|
1007
|
+
value['Selection'] = configured[:selection].to_s if configured.key?(:selection)
|
|
1008
|
+
value['TextTemplate'] = client_template_doc(configured[:text]) if configured.key?(:text)
|
|
1009
|
+
value['AttributeRef'] = attribute_ref_doc(configured[:attribute]) if configured.key?(:attribute)
|
|
1010
|
+
value['EntityRef'] = indirect_entity_ref_doc(configured[:association]) if configured.key?(:association)
|
|
1011
|
+
configure_widget_data_source!(value, configured[:data_source]) if configured.key?(:data_source)
|
|
1012
|
+
configure_widget_children!(value, configured[:widgets]) if configured.key?(:widgets)
|
|
1013
|
+
configure_widget_objects!(property, value, configured[:objects]) if configured.key?(:objects)
|
|
1014
|
+
value
|
|
1015
|
+
end
|
|
1016
|
+
|
|
1017
|
+
def semantic_widget_value?(value)
|
|
1018
|
+
value.is_a?(Hash) && (value.keys.map(&:to_sym) & %i[
|
|
1019
|
+
primitive expression selection text attribute association data_source widgets objects
|
|
1020
|
+
]).any?
|
|
1021
|
+
end
|
|
899
1022
|
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
1023
|
+
def configure_widget_data_source!(value, configured)
|
|
1024
|
+
options = configured.is_a?(Hash) ? configured : { entity: configured }
|
|
1025
|
+
value['DataSource'] = custom_xpath_source_doc(
|
|
1026
|
+
options.fetch(:entity), xpath: options.fetch(:xpath, '')
|
|
1027
|
+
)
|
|
1028
|
+
end
|
|
1029
|
+
|
|
1030
|
+
def configure_widget_children!(value, widgets)
|
|
1031
|
+
children = (widgets.is_a?(Array) ? widgets : [widgets]).compact.map { widget_doc(_1) }
|
|
1032
|
+
value['Widgets'] = IO::BsonCodec.build_array(children, marker: 2)
|
|
1033
|
+
end
|
|
1034
|
+
|
|
1035
|
+
def configure_widget_objects!(property, value, configurations)
|
|
1036
|
+
object_type = property.dig('ValueType', 'ObjectType')
|
|
1037
|
+
objects = Array(configurations).map do |configuration|
|
|
1038
|
+
object = custom_widget_object_doc(object_type)
|
|
1039
|
+
nested = widget_object_properties(object_type, object)
|
|
1040
|
+
configuration.each do |key, configured|
|
|
1041
|
+
configure_custom_widget_value!(nested.fetch(key.to_s), configured)
|
|
904
1042
|
end
|
|
1043
|
+
object
|
|
905
1044
|
end
|
|
1045
|
+
value['Objects'] = IO::BsonCodec.build_array(objects, marker: 2)
|
|
906
1046
|
end
|
|
907
1047
|
|
|
908
1048
|
def stringify_keys(value)
|
|
@@ -946,6 +1086,15 @@ module Mxrb
|
|
|
946
1086
|
if options[:entity] && properties["datasource"]
|
|
947
1087
|
properties["datasource"]["Value"]["DataSource"] = custom_xpath_source_doc(options[:entity])
|
|
948
1088
|
end
|
|
1089
|
+
if options[:selection] && properties['itemSelection']
|
|
1090
|
+
properties.dig('itemSelection', 'Value')['Selection'] = options[:selection].to_s
|
|
1091
|
+
end
|
|
1092
|
+
if properties['filtersPlaceholder'] && options[:filters]
|
|
1093
|
+
configured_filters = options[:filters].is_a?(Array) ? options[:filters] : [options[:filters]]
|
|
1094
|
+
filters = configured_filters.map { widget_doc(_1) }
|
|
1095
|
+
properties.dig('filtersPlaceholder', 'Value')['Widgets'] =
|
|
1096
|
+
IO::BsonCodec.build_array(filters, marker: 2)
|
|
1097
|
+
end
|
|
949
1098
|
return unless properties["columns"] && options[:columns]
|
|
950
1099
|
|
|
951
1100
|
column_type = properties["columns"].dig("ValueType", "ObjectType")
|
|
@@ -1011,16 +1160,20 @@ module Mxrb
|
|
|
1011
1160
|
end
|
|
1012
1161
|
|
|
1013
1162
|
def custom_widget_properties(widget)
|
|
1014
|
-
|
|
1163
|
+
widget_object_properties(widget.dig('Type', 'ObjectType'), widget['Object'])
|
|
1164
|
+
end
|
|
1165
|
+
|
|
1166
|
+
def widget_object_properties(object_type, object)
|
|
1167
|
+
types = array_items(object_type&.fetch('PropertyTypes', nil)).to_h do |type|
|
|
1015
1168
|
[IO::BsonCodec.extract_id(type["$ID"]), type]
|
|
1016
1169
|
end
|
|
1017
|
-
array_items(
|
|
1170
|
+
array_items(object&.fetch('Properties', nil)).to_h do |property|
|
|
1018
1171
|
type = types[IO::BsonCodec.extract_id(property["TypePointer"])]
|
|
1019
1172
|
[type && type["PropertyKey"], property.merge("ValueType" => type && type["ValueType"])]
|
|
1020
1173
|
end.compact
|
|
1021
1174
|
end
|
|
1022
1175
|
|
|
1023
|
-
def custom_xpath_source_doc(entity)
|
|
1176
|
+
def custom_xpath_source_doc(entity, xpath: '')
|
|
1024
1177
|
{
|
|
1025
1178
|
"$ID" => SecureRandom.uuid, "$Type" => "CustomWidgets$CustomWidgetXPathSource",
|
|
1026
1179
|
"EntityRef" => {
|
|
@@ -1032,19 +1185,24 @@ module Mxrb
|
|
|
1032
1185
|
"$ID" => SecureRandom.uuid, "$Type" => "Forms$GridSortBar",
|
|
1033
1186
|
"SortItems" => IO::BsonCodec.build_array([], marker: 2)
|
|
1034
1187
|
},
|
|
1035
|
-
"SourceVariable" => nil, "XPathConstraint" =>
|
|
1188
|
+
"SourceVariable" => nil, "XPathConstraint" => xpath.to_s
|
|
1036
1189
|
}
|
|
1037
1190
|
end
|
|
1038
1191
|
|
|
1039
1192
|
def data_grid2_column_doc(object_type, column, entity: nil)
|
|
1040
1193
|
attribute = column[:attribute]
|
|
1041
1194
|
attribute = "#{entity}.#{attribute}" if entity && attribute && !attribute.include?('.')
|
|
1195
|
+
filters = column[:filter].is_a?(Array) ? column[:filter] : [column[:filter]].compact
|
|
1042
1196
|
overrides = {
|
|
1043
1197
|
"showContentAs" => { "PrimitiveValue" => "attribute" },
|
|
1044
1198
|
"attribute" => { "AttributeRef" => attribute_ref_doc(attribute) },
|
|
1045
1199
|
"header" => { "TextTemplate" => client_template_doc(column[:caption] || column[:name]) },
|
|
1046
1200
|
"tooltip" => { "TextTemplate" => empty_client_template_doc },
|
|
1047
|
-
"filter" => {
|
|
1201
|
+
"filter" => {
|
|
1202
|
+
"Widgets" => IO::BsonCodec.build_array(
|
|
1203
|
+
filters.map { widget_doc(_1) }, marker: 2
|
|
1204
|
+
)
|
|
1205
|
+
}
|
|
1048
1206
|
}
|
|
1049
1207
|
custom_widget_object_doc(object_type, overrides)
|
|
1050
1208
|
end
|
|
@@ -1090,6 +1248,7 @@ module Mxrb
|
|
|
1090
1248
|
def preserve_flow_metadata(merged, existing, generated)
|
|
1091
1249
|
{
|
|
1092
1250
|
"AllowConcurrentExecution" => "__mxrb_allow_concurrent_execution_declared",
|
|
1251
|
+
"ApplyEntityAccess" => "__mxrb_apply_entity_access_declared",
|
|
1093
1252
|
"MarkAsUsed" => "__mxrb_mark_as_used_declared",
|
|
1094
1253
|
"Excluded" => "__mxrb_excluded_declared"
|
|
1095
1254
|
}.each do |field, declaration|
|
|
@@ -1360,7 +1519,7 @@ module Mxrb
|
|
|
1360
1519
|
previous&.dig(rules_key) || IO::BsonCodec.build_array([])
|
|
1361
1520
|
end
|
|
1362
1521
|
doc = (previous || {}).merge(
|
|
1363
|
-
"$ID" => id, "$Type" => "DomainModels$EntityImpl",
|
|
1522
|
+
"$ID" => id, "$Type" => previous&.fetch("$Type", nil) || "DomainModels$EntityImpl",
|
|
1364
1523
|
"Name" => entity.fetch(:name), "Documentation" => entity.fetch(:documentation, ""),
|
|
1365
1524
|
"GUID" => previous&.dig("GUID") || SecureRandom.uuid,
|
|
1366
1525
|
"Location" => previous&.dig("Location") || "#{(index % 4) * 220};#{(index / 4) * 160}",
|
|
@@ -1368,6 +1527,7 @@ module Mxrb
|
|
|
1368
1527
|
"IsRemote" => previous&.fetch("IsRemote", false) || false,
|
|
1369
1528
|
"RemoteSource" => previous&.fetch("RemoteSource", "") || ""
|
|
1370
1529
|
)
|
|
1530
|
+
apply_oql_view!(doc, entity.fetch(:oql_view, nil), previous)
|
|
1371
1531
|
doc[attrs_key] = IO::BsonCodec.build_array(attrs)
|
|
1372
1532
|
doc[rules_key] = access_rules
|
|
1373
1533
|
doc[validation_key] = validation_rules_doc(
|
|
@@ -1397,8 +1557,27 @@ module Mxrb
|
|
|
1397
1557
|
doc
|
|
1398
1558
|
end
|
|
1399
1559
|
|
|
1560
|
+
def apply_oql_view!(doc, view, previous)
|
|
1561
|
+
return unless view
|
|
1562
|
+
|
|
1563
|
+
if view[:source]
|
|
1564
|
+
source_key = native_existing_key(previous, 'source', 'Source') || 'Source'
|
|
1565
|
+
current_source = previous&.dig(source_key)
|
|
1566
|
+
source = (current_source.is_a?(Hash) ? current_source : {}).merge(
|
|
1567
|
+
'$ID' => current_source&.fetch('$ID', nil) || SecureRandom.uuid,
|
|
1568
|
+
'$Type' => 'DomainModels$OqlViewEntitySource',
|
|
1569
|
+
'SourceDocument' => view.fetch(:source)
|
|
1570
|
+
)
|
|
1571
|
+
doc[source_key] = source
|
|
1572
|
+
end
|
|
1573
|
+
return unless view[:query]
|
|
1574
|
+
|
|
1575
|
+
query_key = native_existing_key(previous, 'oqlQuery', 'OqlQuery', 'OQLQuery') || 'OqlQuery'
|
|
1576
|
+
doc[query_key] = view.fetch(:query)
|
|
1577
|
+
end
|
|
1578
|
+
|
|
1400
1579
|
def attribute_doc(attr, previous)
|
|
1401
|
-
storage_type = Model::Attribute::TYPE_MAP.fetch(attr.fetch(:type))
|
|
1580
|
+
storage_type = Model::Attribute::TYPE_MAP.fetch(attr.fetch(:type).to_sym)
|
|
1402
1581
|
type_key = native_existing_key(previous, "type", "Type", "newType", "NewType") || "NewType"
|
|
1403
1582
|
value_key = native_existing_key(previous, "value", "Value") || "Value"
|
|
1404
1583
|
name_key = native_key(previous, "name", "Name")
|
|
@@ -1410,9 +1589,11 @@ module Mxrb
|
|
|
1410
1589
|
{ "$ID" => SecureRandom.uuid, "$Type" => storage_type }
|
|
1411
1590
|
end
|
|
1412
1591
|
type_doc = type_doc.merge("Enumeration" => attr[:enumeration].to_s) if attr[:enumeration]
|
|
1413
|
-
|
|
1592
|
+
string_type = storage_type == Model::Attribute::TYPE_MAP[:string]
|
|
1593
|
+
if attr[:length] || (string_type && !previous_type&.key?('length') && !previous_type&.key?('Length'))
|
|
1414
1594
|
length_key = native_key(previous_type, 'length', 'Length')
|
|
1415
|
-
|
|
1595
|
+
length = attr[:length] || Model::Attribute::DEFAULT_STRING_LENGTH
|
|
1596
|
+
type_doc = type_doc.merge(length_key => Integer(length))
|
|
1416
1597
|
end
|
|
1417
1598
|
if attr.key?(:localize_date)
|
|
1418
1599
|
localize_key = native_key(previous_type, 'localizeDate', 'LocalizeDate')
|
|
@@ -2198,6 +2379,48 @@ module Mxrb
|
|
|
2198
2379
|
}
|
|
2199
2380
|
end
|
|
2200
2381
|
|
|
2382
|
+
# A project created outside Studio Pro may not have the pluggable-widget
|
|
2383
|
+
# package available yet. These standard-shaped fallback fields preserve
|
|
2384
|
+
# the concise Ruby projection until Studio Pro can hydrate the widget.
|
|
2385
|
+
def configure_fallback_data_grid!(doc, options)
|
|
2386
|
+
entity = options[:entity].to_s
|
|
2387
|
+
columns = Array(options[:columns]).map do |column|
|
|
2388
|
+
attribute = column[:attribute].to_s
|
|
2389
|
+
attribute = "#{entity}.#{attribute}" if !entity.empty? && !attribute.empty? && !attribute.include?('.')
|
|
2390
|
+
{
|
|
2391
|
+
'$ID' => SecureRandom.uuid, '$Type' => 'Forms$DataGridColumn',
|
|
2392
|
+
'Name' => column[:name].to_s,
|
|
2393
|
+
'AttributeRef' => attribute_ref_doc(attribute),
|
|
2394
|
+
'Caption' => text_doc(column[:caption] || column[:name])
|
|
2395
|
+
}
|
|
2396
|
+
end
|
|
2397
|
+
toolbar = Array(options.dig(:toolbar, :buttons)).map do |button|
|
|
2398
|
+
kind = { new: 'New', delete: 'Delete', search: 'Search', export: 'ExportToExcel' }
|
|
2399
|
+
.fetch(button[:type].to_sym)
|
|
2400
|
+
{
|
|
2401
|
+
'$ID' => SecureRandom.uuid, '$Type' => "Forms$Grid#{kind}Button",
|
|
2402
|
+
'Caption' => text_doc(button[:caption].to_s)
|
|
2403
|
+
}
|
|
2404
|
+
end
|
|
2405
|
+
doc['DataSource'] = {
|
|
2406
|
+
'$ID' => SecureRandom.uuid, '$Type' => 'Forms$DatabaseSource', 'Entity' => entity
|
|
2407
|
+
}
|
|
2408
|
+
doc['Columns'] = IO::BsonCodec.build_array(columns)
|
|
2409
|
+
doc['ToolBar'] = {
|
|
2410
|
+
'$ID' => SecureRandom.uuid, '$Type' => 'Forms$GridControlBar',
|
|
2411
|
+
'Buttons' => IO::BsonCodec.build_array(toolbar)
|
|
2412
|
+
}
|
|
2413
|
+
doc
|
|
2414
|
+
end
|
|
2415
|
+
|
|
2416
|
+
def configure_fallback_combo_box!(doc, options)
|
|
2417
|
+
doc['AttributePath'] = options[:attribute].to_s if options[:attribute]
|
|
2418
|
+
doc['LabelText'] = text_doc(options[:caption]) if options.key?(:caption)
|
|
2419
|
+
doc['SelectorType'] = options[:__kind].to_sym == :reference_selector ? 'Reference' : 'Enumeration'
|
|
2420
|
+
doc['DisplayAttribute'] = options[:display_attribute].to_s if options[:display_attribute]
|
|
2421
|
+
doc
|
|
2422
|
+
end
|
|
2423
|
+
|
|
2201
2424
|
def combo_box_descriptor
|
|
2202
2425
|
{
|
|
2203
2426
|
id: "com.mendix.widget.web.combobox.Combobox", name: "Combo box",
|
|
@@ -2244,6 +2467,15 @@ module Mxrb
|
|
|
2244
2467
|
configure_data_grid2!(doc, options) if descriptor.fetch(:id) == data_grid2_descriptor[:id]
|
|
2245
2468
|
configure_combo_box!(doc, options) if descriptor.fetch(:id) == combo_box_descriptor[:id]
|
|
2246
2469
|
configure_pluggable_widget!(doc, options) if widget.fetch(:type) == :pluggable_widget
|
|
2470
|
+
if definition.nil? && descriptor.fetch(:id) == data_grid2_descriptor[:id]
|
|
2471
|
+
configure_fallback_data_grid!(doc, options)
|
|
2472
|
+
end
|
|
2473
|
+
if definition.nil? && descriptor.fetch(:id) == combo_box_descriptor[:id]
|
|
2474
|
+
configure_fallback_combo_box!(doc, options)
|
|
2475
|
+
end
|
|
2476
|
+
widget.fetch(:events, []).each do |event|
|
|
2477
|
+
doc[event_property(event.fetch(:event))] = client_action_doc(event)
|
|
2478
|
+
end
|
|
2247
2479
|
doc
|
|
2248
2480
|
end
|
|
2249
2481
|
|
|
@@ -2404,6 +2636,8 @@ module Mxrb
|
|
|
2404
2636
|
case event.fetch(:kind).to_sym
|
|
2405
2637
|
when :action
|
|
2406
2638
|
native_action_doc(event.fetch(:handler))
|
|
2639
|
+
when :page
|
|
2640
|
+
form_action_doc(event.fetch(:handler))
|
|
2407
2641
|
when :nanoflow
|
|
2408
2642
|
{
|
|
2409
2643
|
"$ID" => SecureRandom.uuid,
|
|
@@ -2523,6 +2757,7 @@ module Mxrb
|
|
|
2523
2757
|
body_declared = !flow[:body].nil? || !flow[:return_expression].nil?
|
|
2524
2758
|
return_var_name = flow[:return_variable_name] || "ReturnValue"
|
|
2525
2759
|
allow_concurrent = flow[:allow_concurrent_execution]
|
|
2760
|
+
apply_entity_access = flow[:apply_entity_access]
|
|
2526
2761
|
mark_as_used = flow[:mark_as_used]
|
|
2527
2762
|
excluded = flow[:excluded]
|
|
2528
2763
|
|
|
@@ -2540,6 +2775,7 @@ module Mxrb
|
|
|
2540
2775
|
"Name" => flow_name, "Documentation" => flow.fetch(:documentation, ""),
|
|
2541
2776
|
"ReturnVariableName" => return_var_name,
|
|
2542
2777
|
"AllowConcurrentExecution" => allow_concurrent.nil? ? true : allow_concurrent,
|
|
2778
|
+
"ApplyEntityAccess" => apply_entity_access.nil? ? false : apply_entity_access,
|
|
2543
2779
|
"MarkAsUsed" => mark_as_used.nil? ? false : mark_as_used,
|
|
2544
2780
|
"Excluded" => excluded.nil? ? false : excluded,
|
|
2545
2781
|
"AllowedModuleRoles" => IO::BsonCodec.build_array(Array(flow[:allowed_roles]), marker: 1),
|
|
@@ -2547,6 +2783,7 @@ module Mxrb
|
|
|
2547
2783
|
"__mxrb_body_declared" => body_declared,
|
|
2548
2784
|
"__mxrb_preserve_native_body" => flow[:preserve_native_body] == true,
|
|
2549
2785
|
"__mxrb_allow_concurrent_execution_declared" => !allow_concurrent.nil?,
|
|
2786
|
+
"__mxrb_apply_entity_access_declared" => !apply_entity_access.nil?,
|
|
2550
2787
|
"__mxrb_mark_as_used_declared" => !mark_as_used.nil?,
|
|
2551
2788
|
"__mxrb_excluded_declared" => !excluded.nil?,
|
|
2552
2789
|
"MicroflowReturnType" => microflow_data_type_doc(flow[:return_type], module_name),
|
data/lib/mxrb.rb
CHANGED
|
@@ -2,9 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
require_relative "mxrb/version"
|
|
4
4
|
require_relative "mxrb/errors"
|
|
5
|
+
require_relative "mxrb/http/server"
|
|
6
|
+
require_relative "mxrb/progress"
|
|
5
7
|
require_relative "mxrb/doctor"
|
|
6
8
|
require_relative "mxrb/benchmark"
|
|
7
9
|
require_relative "mxrb/project_lifecycle"
|
|
10
|
+
require_relative "mxrb/environment"
|
|
8
11
|
require_relative "mxrb/scaffold/templates"
|
|
9
12
|
require_relative "mxrb/scaffold/page_templates"
|
|
10
13
|
require_relative "mxrb/initializer"
|
|
@@ -15,8 +18,11 @@ require_relative "mxrb/scaffold/recipes"
|
|
|
15
18
|
require_relative "mxrb/scaffold/generator"
|
|
16
19
|
require_relative "mxrb/scaffold/help"
|
|
17
20
|
require_relative "mxrb/scaffold/cli"
|
|
21
|
+
require_relative "mxrb/cli/help"
|
|
22
|
+
require_relative "mxrb/cli/release"
|
|
18
23
|
require_relative "mxrb/io/bson_codec"
|
|
19
24
|
require_relative "mxrb/widget_package"
|
|
25
|
+
require_relative "mxrb/widget_certification"
|
|
20
26
|
require_relative "mxrb/frontend/migrator"
|
|
21
27
|
require_relative "mxrb/io/mxunit_codec"
|
|
22
28
|
require_relative "mxrb/io/mpr_file"
|
|
@@ -35,6 +41,13 @@ require_relative "mxrb/model/design_migration"
|
|
|
35
41
|
require_relative "mxrb/model/module"
|
|
36
42
|
require_relative "mxrb/model/connector"
|
|
37
43
|
require_relative "mxrb/model/project"
|
|
44
|
+
require_relative "mxrb/modeler/catalog"
|
|
45
|
+
require_relative "mxrb/domain_diagram"
|
|
46
|
+
require_relative "mxrb/domain_diagram/lifecycle"
|
|
47
|
+
require_relative "mxrb/uml/class_diagram"
|
|
48
|
+
require_relative "mxrb/uml/activity_diagram"
|
|
49
|
+
require_relative "mxrb/uml/sequence_diagram"
|
|
50
|
+
require_relative "mxrb/uml/server"
|
|
38
51
|
require_relative "mxrb/protocols"
|
|
39
52
|
require_relative "mxrb/oql"
|
|
40
53
|
require_relative "mxrb/oql/plan_analyzer"
|
|
@@ -115,6 +128,7 @@ require_relative "mxrb/compiler/image_bundle_compiler"
|
|
|
115
128
|
require_relative "mxrb/compiler/generic_widget_bundle_compiler"
|
|
116
129
|
require_relative "mxrb/compiler/combo_box_bundle_compiler"
|
|
117
130
|
require_relative "mxrb/compiler/legacy_data_grid_compiler"
|
|
131
|
+
require_relative "mxrb/compiler/legacy_custom_widget_compiler"
|
|
118
132
|
require_relative "mxrb/compiler/legacy_page_builder"
|
|
119
133
|
require_relative "mxrb/compiler/page_bundle_compiler"
|
|
120
134
|
require_relative "mxrb/compiler/compatibility_analyzer"
|
|
@@ -125,6 +139,14 @@ require_relative "mxrb/widget_synchronizer"
|
|
|
125
139
|
require_relative "mxrb/runtime/docker_workspace"
|
|
126
140
|
require_relative "mxrb/runtime/executor"
|
|
127
141
|
require_relative "mxrb/runtime/native"
|
|
142
|
+
require_relative "mxrb/runtime/schema_migrator"
|
|
143
|
+
require_relative "mxrb/runtime/sqlite_store"
|
|
144
|
+
require_relative "mxrb/runtime/access_control"
|
|
145
|
+
require_relative "mxrb/runtime/shared_store"
|
|
146
|
+
require_relative "mxrb/runtime/scheduler"
|
|
147
|
+
require_relative "mxrb/ruby_app"
|
|
148
|
+
require_relative "mxrb/ruby_app/preset"
|
|
149
|
+
require_relative "mxrb/ruby_app/exporter"
|
|
128
150
|
require_relative "mxrb/runtime/docker_executor"
|
|
129
151
|
require_relative "mxrb/runtime/clipboard"
|
|
130
152
|
require_relative "mxrb/runtime/database_workspace"
|
|
@@ -139,14 +161,18 @@ module Mxrb
|
|
|
139
161
|
#
|
|
140
162
|
# Mxrb.open("MyApp.mpr") { |p| puts p.modules.map(&:name) }
|
|
141
163
|
#
|
|
142
|
-
def self.open(path, readonly: true, &block)
|
|
143
|
-
|
|
144
|
-
return project unless block
|
|
164
|
+
def self.open(path, readonly: true, &block) # rubocop:disable Metrics/MethodLength
|
|
165
|
+
return Model::Project.open(path, readonly: readonly) unless block
|
|
145
166
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
167
|
+
Progress.with("Loading #{File.basename(path)}") do |progress|
|
|
168
|
+
progress.update(detail: "opening model")
|
|
169
|
+
project = Model::Project.open(path, readonly: readonly)
|
|
170
|
+
begin
|
|
171
|
+
progress.update(detail: "processing model")
|
|
172
|
+
block.call(project)
|
|
173
|
+
ensure
|
|
174
|
+
project.close
|
|
175
|
+
end
|
|
150
176
|
end
|
|
151
177
|
end
|
|
152
178
|
|
|
@@ -164,9 +190,13 @@ module Mxrb
|
|
|
164
190
|
#
|
|
165
191
|
def self.define(path, &block)
|
|
166
192
|
output = ENV.fetch("MXRB_OUTPUT_PATH", path)
|
|
167
|
-
Dsl::Builder.new(output).tap { _1.instance_eval(&block) }.build!
|
|
193
|
+
builder = Dsl::Builder.new(output).tap { _1.instance_eval(&block) }.build!
|
|
194
|
+
@last_defined_path = builder.path
|
|
195
|
+
builder
|
|
168
196
|
end
|
|
169
197
|
|
|
198
|
+
def self.last_defined_path = @last_defined_path
|
|
199
|
+
|
|
170
200
|
def self.validate(path)
|
|
171
201
|
Integrity::Validator.new(path).validate
|
|
172
202
|
end
|