datex-studio-cli 0.4.6__tar.gz → 0.4.7__tar.gz

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.
Files changed (172) hide show
  1. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/PKG-INFO +1 -1
  2. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/pyproject.toml +1 -1
  3. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/__init__.py +1 -1
  4. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/cli.py +4 -2
  5. datex_studio_cli-0.4.7/src/dxs/commands/configuration.py +533 -0
  6. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/commands/crm.py +353 -13
  7. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/commands/datasource.py +41 -64
  8. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/commands/function.py +1 -53
  9. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/commands/report/api.py +7 -2
  10. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/commands/report/create.py +30 -6
  11. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/commands/report/folder.py +38 -5
  12. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/commands/studio.py +159 -25
  13. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/api/app_config.py +41 -1
  14. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/api/endpoints.py +15 -0
  15. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/datasource/generator.py +81 -30
  16. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/datasource/resolver.py +1 -1
  17. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/dynamics/client.py +80 -12
  18. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/report/engine.py +47 -9
  19. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/report/preview_arjs.py +52 -7
  20. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/utils/resolvers.py +60 -28
  21. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/web/static/report-validate.html +18 -1
  22. datex_studio_cli-0.4.6/src/dxs/commands/configuration.py +0 -250
  23. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/.gitignore +0 -0
  24. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/README.md +0 -0
  25. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/report-creator.skill +0 -0
  26. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/scripts/analyze_corpus.py +0 -0
  27. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/scripts/generate_rdlx_schema.py +0 -0
  28. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/__main__.py +0 -0
  29. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/commands/__init__.py +0 -0
  30. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/commands/api.py +0 -0
  31. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/commands/auth.py +0 -0
  32. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/commands/branch.py +0 -0
  33. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/commands/config.py +0 -0
  34. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/commands/devops.py +0 -0
  35. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/commands/document.py +0 -0
  36. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/commands/endpoint.py +0 -0
  37. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/commands/env.py +0 -0
  38. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/commands/explore.py +0 -0
  39. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/commands/marketplace.py +0 -0
  40. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/commands/odata.py +0 -0
  41. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/commands/organization.py +0 -0
  42. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/commands/proxy.py +0 -0
  43. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/commands/release_notes.py +0 -0
  44. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/commands/repo.py +0 -0
  45. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/commands/report/__init__.py +0 -0
  46. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/commands/report/add_cmds.py +0 -0
  47. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/commands/report/batch.py +0 -0
  48. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/commands/report/data.py +0 -0
  49. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/commands/report/dataset.py +0 -0
  50. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/commands/report/edit.py +0 -0
  51. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/commands/report/preview.py +0 -0
  52. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/commands/report/schema_cmds.py +0 -0
  53. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/commands/schema.py +0 -0
  54. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/commands/servicepack.py +0 -0
  55. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/commands/source.py +0 -0
  56. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/commands/telemetry.py +0 -0
  57. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/commands/user.py +0 -0
  58. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/context.py +0 -0
  59. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/__init__.py +0 -0
  60. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/api/__init__.py +0 -0
  61. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/api/client.py +0 -0
  62. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/api/metadata_models.py +0 -0
  63. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/api/models.py +0 -0
  64. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/auth/__init__.py +0 -0
  65. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/auth/decorators.py +0 -0
  66. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/auth/msal_client.py +0 -0
  67. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/auth/token_cache.py +0 -0
  68. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/cache.py +0 -0
  69. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/datasource/__init__.py +0 -0
  70. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/datasource/flow_generator.py +0 -0
  71. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/datasource/flow_models.py +0 -0
  72. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/datasource/models.py +0 -0
  73. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/datasource/parsers.py +0 -0
  74. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/datasource/type_def_parser.py +0 -0
  75. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/datasource/validator.py +0 -0
  76. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/designer/__init__.py +0 -0
  77. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/designer/flow_models.py +0 -0
  78. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/designer/models.py +0 -0
  79. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/designer/parsers.py +0 -0
  80. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/devops/__init__.py +0 -0
  81. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/devops/client.py +0 -0
  82. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/devops/helpers.py +0 -0
  83. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/devops/models.py +0 -0
  84. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/dynamics/__init__.py +0 -0
  85. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/dynamics/metadata_cache.py +0 -0
  86. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/footprint/__init__.py +0 -0
  87. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/footprint/client.py +0 -0
  88. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/footprint/edmx_parser.py +0 -0
  89. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/footprint/metadata.py +0 -0
  90. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/function/__init__.py +0 -0
  91. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/function/generator.py +0 -0
  92. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/function/models.py +0 -0
  93. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/function/validator.py +0 -0
  94. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/graph.py +0 -0
  95. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/output/__init__.py +0 -0
  96. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/output/csv_fmt.py +0 -0
  97. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/output/formatter.py +0 -0
  98. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/output/json_fmt.py +0 -0
  99. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/output/redaction.py +0 -0
  100. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/output/yaml_fmt.py +0 -0
  101. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/release_notes.py +0 -0
  102. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/responses.py +0 -0
  103. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/telemetry/__init__.py +0 -0
  104. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/telemetry/config.py +0 -0
  105. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/telemetry/identity.py +0 -0
  106. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/telemetry/recorder.py +0 -0
  107. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/telemetry/scrubber.py +0 -0
  108. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/core/telemetry/sender.py +0 -0
  109. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/models/__init__.py +0 -0
  110. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/report/__init__.py +0 -0
  111. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/report/datasource_binding.py +0 -0
  112. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/report/field_parser.py +0 -0
  113. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/report/folder.py +0 -0
  114. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/report/manifest.py +0 -0
  115. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/report/models.py +0 -0
  116. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/report/preview.py +0 -0
  117. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/report/schema.py +0 -0
  118. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/report/svg_renderer.py +0 -0
  119. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/report/templates/__init__.py +0 -0
  120. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/report/templates/bill_of_lading.rdlx-json +0 -0
  121. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/report/templates/shipping_label.rdlx-json +0 -0
  122. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/report/validate_arjs.py +0 -0
  123. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/report/validator.py +0 -0
  124. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/report/wrapper.py +0 -0
  125. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/utils/__init__.py +0 -0
  126. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/utils/click_options.py +0 -0
  127. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/utils/config.py +0 -0
  128. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/utils/errors.py +0 -0
  129. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/utils/filtering.py +0 -0
  130. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/utils/image.py +0 -0
  131. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/utils/paths.py +0 -0
  132. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/utils/responses.py +0 -0
  133. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/utils/restricted.py +0 -0
  134. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/utils/sorting.py +0 -0
  135. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/utils/update_check.py +0 -0
  136. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/web/__init__.py +0 -0
  137. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/web/app.py +0 -0
  138. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/web/design.py +0 -0
  139. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/web/proxy_app.py +0 -0
  140. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/web/static/404/index.html +0 -0
  141. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/web/static/404.html +0 -0
  142. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/web/static/_next/static/UgyAMtPjH-Pt0RYWOHzIT/_buildManifest.js +0 -0
  143. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/web/static/_next/static/UgyAMtPjH-Pt0RYWOHzIT/_ssgManifest.js +0 -0
  144. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/web/static/_next/static/chunks/0b24cca5-c1e1c8810348f107.js +0 -0
  145. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/web/static/_next/static/chunks/255-102f2e5b2e3dc2ef.js +0 -0
  146. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/web/static/_next/static/chunks/4bd1b696-c023c6e3521b1417.js +0 -0
  147. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/web/static/_next/static/chunks/538-84e2e111415f1fda.js +0 -0
  148. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/web/static/_next/static/chunks/697-0e000ab410d9f470.js +0 -0
  149. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/web/static/_next/static/chunks/871-1acacdb7b4022abf.js +0 -0
  150. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/web/static/_next/static/chunks/8b8f67fc-6295949a4b5485a4.js +0 -0
  151. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/web/static/_next/static/chunks/909-c88abba3cf0caec3.js +0 -0
  152. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/web/static/_next/static/chunks/app/_not-found/page-ea1be7001c230704.js +0 -0
  153. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/web/static/_next/static/chunks/app/design/capture/page-a5e129c2d223432c.js +0 -0
  154. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/web/static/_next/static/chunks/app/design/page-21ba66a3dd3b03f0.js +0 -0
  155. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/web/static/_next/static/chunks/app/layout-2cc6eac09e476c91.js +0 -0
  156. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/web/static/_next/static/chunks/app/page-20c358395882cdac.js +0 -0
  157. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/web/static/_next/static/chunks/framework-de98b93a850cfc71.js +0 -0
  158. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/web/static/_next/static/chunks/main-0f18f91200dac003.js +0 -0
  159. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/web/static/_next/static/chunks/main-app-b69998d8941231d8.js +0 -0
  160. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/web/static/_next/static/chunks/pages/_app-7d307437aca18ad4.js +0 -0
  161. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/web/static/_next/static/chunks/pages/_error-cb2a52f75f2162e2.js +0 -0
  162. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/web/static/_next/static/chunks/polyfills-42372ed130431b0a.js +0 -0
  163. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/web/static/_next/static/chunks/webpack-2b297ada5306c17f.js +0 -0
  164. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/web/static/_next/static/css/360c657de5e04df8.css +0 -0
  165. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/web/static/design/capture/index.html +0 -0
  166. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/web/static/design/capture/index.txt +0 -0
  167. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/web/static/design/index.html +0 -0
  168. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/web/static/design/index.txt +0 -0
  169. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/web/static/index.html +0 -0
  170. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/web/static/index.txt +0 -0
  171. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/web/static/render-cli.js +0 -0
  172. {datex_studio_cli-0.4.6 → datex_studio_cli-0.4.7}/src/dxs/web/static/report-preview.html +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: datex-studio-cli
3
- Version: 0.4.6
3
+ Version: 0.4.7
4
4
  Summary: CLI for Datex Studio low-code platform, designed for LLM-based AI agents
5
5
  Project-URL: Homepage, https://github.com/datex/datex-studio-cli
6
6
  Project-URL: Documentation, https://github.com/datex/datex-studio-cli
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "datex-studio-cli"
7
- version = "0.4.6"
7
+ version = "0.4.7"
8
8
  description = "CLI for Datex Studio low-code platform, designed for LLM-based AI agents"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -1,4 +1,4 @@
1
1
  """Datex Studio CLI - Command-line interface for Datex Studio platform."""
2
2
 
3
- __version__ = "0.4.6"
3
+ __version__ = "0.4.7"
4
4
  __app_name__ = "dxs"
@@ -390,8 +390,10 @@ def handle_errors(f: F) -> F:
390
390
  _record_error_silently(e)
391
391
  dxs_ctx.output_error(e)
392
392
  sys.exit(1)
393
- except click.ClickException:
394
- # Let Click handle its own exceptions
393
+ except (click.ClickException, click.Abort, click.exceptions.Exit):
394
+ # Let Click handle its own exceptions and control-flow signals
395
+ # (Abort from confirm(abort=True), Exit from ctx.exit) — these are
396
+ # not errors and must not be rendered as error envelopes.
395
397
  raise
396
398
  except Exception as e:
397
399
  _record_error_silently(e)
@@ -0,0 +1,533 @@
1
+ """Generic platform configuration commands: dxs configuration [get|create|update|upsert|validate|list|delete|contexts|types].
2
+
3
+ Canonical CRUD surface for any of ConfigurationEndpoints.KNOWN_TYPES
4
+ (hub, grid, form, editor, flow, etc.). Provides the missing primitive
5
+ that previously forced users to hand-craft `dxs api` calls and
6
+ reverse-engineer endpoint paths.
7
+
8
+ Verb vocabulary:
9
+ - `create` — POST, fails if exists. Requires the caller to know the
10
+ config does not already exist on the branch.
11
+ - `update` — PUT, requires the numeric ID. Requires the caller to know
12
+ the config exists.
13
+ - `upsert` — orchestrated create-or-update by referenceName, handles
14
+ the Datex Studio source-control lock protocol on the caller's behalf.
15
+ This is the right verb when the caller does not know which case
16
+ applies.
17
+ """
18
+
19
+ from __future__ import annotations
20
+
21
+ import json
22
+ from pathlib import Path
23
+ from typing import Any
24
+
25
+ import click
26
+
27
+ from dxs.cli import DxsContext, handle_errors, pass_context
28
+ from dxs.core.api.client import ApiClient
29
+ from dxs.core.api.endpoints import ConfigurationEndpoints
30
+ from dxs.core.auth import require_auth
31
+ from dxs.core.designer.parsers import is_valid_js_identifier
32
+ from dxs.utils.click_options import resolve_branch
33
+ from dxs.utils.errors import ValidationError
34
+ from dxs.utils.resolvers import resolve_config_by_reference, upsert_config
35
+ from dxs.utils.responses import list_response, single
36
+ from dxs.utils.restricted import restrict_in_restricted_mode
37
+
38
+
39
+ def _validate_type(config_type: str) -> str:
40
+ normalized = ConfigurationEndpoints.normalize_type(config_type)
41
+ if normalized not in ConfigurationEndpoints.KNOWN_TYPES:
42
+ known = ", ".join(sorted(ConfigurationEndpoints.KNOWN_TYPES))
43
+ raise ValidationError(
44
+ message=f"Unknown configuration type: {config_type!r}",
45
+ code="DXS-CFG-001",
46
+ suggestions=[f"Use one of: {known}"],
47
+ )
48
+ return normalized
49
+
50
+
51
+ def _load_body(data_file: Path) -> Any:
52
+ try:
53
+ return json.loads(data_file.read_text(encoding="utf-8"))
54
+ except json.JSONDecodeError as e:
55
+ raise ValidationError(
56
+ message=f"Invalid JSON in {data_file}: {e}",
57
+ code="DXS-CFG-002",
58
+ suggestions=[f"Validate the file with: python -m json.tool {data_file}"],
59
+ ) from e
60
+
61
+
62
+ @click.group("configuration")
63
+ def configuration() -> None:
64
+ """Manage platform configuration objects (hub, grid, form, editor, flow, etc.).
65
+
66
+ These are the deployable artifacts on a Datex Studio branch — distinct from
67
+ `dxs config`/`dxs settings`, which manage local CLI settings.
68
+
69
+ The CRUD surface is uniform across every type in `dxs configuration types`.
70
+ Pair `get` (with --output-file) and `update` (with --data-file) to fetch a
71
+ config, edit it locally, and push it back without shell-escaping a large
72
+ JSON payload. Use `create` for new configs, `upsert` when you do not know
73
+ whether the config already exists, and `delete` to remove them; `validate`
74
+ and `contexts` run the platform's authoring-time checks.
75
+
76
+ \b
77
+ Examples:
78
+ dxs configuration types
79
+ dxs configuration list hub -b 64
80
+ dxs configuration get hub 8642750 -b 64 --output-file envelope.json
81
+ jq .json envelope.json > body.json # extract inner body for update
82
+ # edit body.json
83
+ dxs configuration update hub 8642750 -b 64 --data-file body.json
84
+ dxs configuration create grid -b 64 --data-file new_grid.json
85
+ dxs configuration upsert datasource -b 64 --data-file ds.json
86
+ dxs configuration validate grid -b 64 --data-file new_grid.json
87
+ dxs configuration delete grid 8642750 -b 64 --yes
88
+ """
89
+
90
+
91
+ @configuration.command("types")
92
+ @pass_context
93
+ def configuration_types(ctx: DxsContext) -> None:
94
+ """List the known platform configuration type names accepted by these commands."""
95
+ types = sorted(ConfigurationEndpoints.KNOWN_TYPES)
96
+ ctx.output(
97
+ single(item={"types": types, "count": len(types)}, semantic_key="configuration_types")
98
+ )
99
+
100
+
101
+ @configuration.command("get")
102
+ @click.argument("config_type")
103
+ @click.argument("config_ref")
104
+ @click.option("--branch", "-b", type=int, default=None, help="Branch ID (falls back to global -b)")
105
+ @click.option(
106
+ "--output-file",
107
+ "-O",
108
+ "output_file",
109
+ type=click.Path(dir_okay=False, writable=True, path_type=Path),
110
+ default=None,
111
+ help=(
112
+ "Write the full server envelope JSON to a file. To round-trip through "
113
+ "`update -D`, first extract the inner body (e.g., `jq .json envelope.json > body.json`)."
114
+ ),
115
+ )
116
+ @pass_context
117
+ @require_auth
118
+ @handle_errors
119
+ def configuration_get(
120
+ ctx: DxsContext,
121
+ config_type: str,
122
+ config_ref: str,
123
+ branch: int | None,
124
+ output_file: Path | None,
125
+ ) -> None:
126
+ """Fetch a platform configuration by type and ID or reference name.
127
+
128
+ \b
129
+ Arguments:
130
+ CONFIG_TYPE Configuration type (e.g., hub, grid, form, editor, flow)
131
+ CONFIG_REF Numeric configuration ID, or the config's reference name.
132
+ Reference names are valid JS identifiers (never all-digits),
133
+ so an all-digit value is always treated as an ID.
134
+
135
+ \b
136
+ Examples:
137
+ dxs configuration get hub 8642750 -b 64
138
+ dxs configuration get hub hub_home -b 64
139
+ dxs configuration get hub hub_home -b 64 -O hub.json
140
+ """
141
+ config_type = _validate_type(config_type)
142
+ branch_id = resolve_branch(ctx, branch, "DXS-CFG-010")
143
+
144
+ api_client = ApiClient()
145
+ if config_ref.isdigit():
146
+ path = ConfigurationEndpoints.get_content(branch_id, config_type, int(config_ref))
147
+ body = api_client.get(path)
148
+ else:
149
+ body = resolve_config_by_reference(api_client, branch_id, config_type, config_ref)
150
+
151
+ if output_file is not None:
152
+ output_file.write_text(
153
+ json.dumps(body, indent=2, ensure_ascii=False),
154
+ encoding="utf-8",
155
+ )
156
+ ctx.log(f"Wrote {config_type} configuration {config_ref} to {output_file}")
157
+ return
158
+
159
+ ctx.output(single(item=body, semantic_key="configuration"))
160
+
161
+
162
+ @configuration.command("update")
163
+ @click.argument("config_type")
164
+ @click.argument("config_ref")
165
+ @click.option(
166
+ "--data-file",
167
+ "-D",
168
+ "data_file",
169
+ required=True,
170
+ type=click.Path(exists=True, dir_okay=False, readable=True, path_type=Path),
171
+ help="JSON file containing the full configuration body to PUT.",
172
+ )
173
+ @click.option("--branch", "-b", type=int, default=None, help="Branch ID (falls back to global -b)")
174
+ @pass_context
175
+ @require_auth
176
+ @handle_errors
177
+ @restrict_in_restricted_mode("modifies platform configurations")
178
+ def configuration_update(
179
+ ctx: DxsContext,
180
+ config_type: str,
181
+ config_ref: str,
182
+ data_file: Path,
183
+ branch: int | None,
184
+ ) -> None:
185
+ """Update a platform configuration via PUT with a body read from a file.
186
+
187
+ The body is read from disk (no shell escaping), so payloads with embedded
188
+ \\r\\n sequences, nested quotes, or large flow code blocks round-trip
189
+ cleanly. The target may be a numeric ID or a reference name (an all-digit
190
+ value is always treated as an ID). For create-or-update by referenceName
191
+ with source-control lock handling, prefer `upsert`.
192
+
193
+ \b
194
+ Examples:
195
+ dxs configuration update hub 8642750 -b 64 -D hub.json
196
+ dxs configuration update hub hub_home -b 64 -D hub.json
197
+ dxs configuration update flow 12345 -b 64 -D flow_body.json
198
+ """
199
+ config_type = _validate_type(config_type)
200
+ branch_id = resolve_branch(ctx, branch, "DXS-CFG-010")
201
+
202
+ body = _load_body(data_file)
203
+ api_client = ApiClient()
204
+ if config_ref.isdigit():
205
+ config_id = int(config_ref)
206
+ else:
207
+ resolved = resolve_config_by_reference(api_client, branch_id, config_type, config_ref)
208
+ config_id = resolved["id"]
209
+ path = ConfigurationEndpoints.update(branch_id, config_type, config_id)
210
+ response = api_client.put(path, data=body)
211
+
212
+ ctx.output(
213
+ single(
214
+ item={
215
+ "id": config_id,
216
+ "type": config_type,
217
+ "branch_id": branch_id,
218
+ "source_file": str(data_file),
219
+ "response": response,
220
+ },
221
+ semantic_key="configuration_update",
222
+ )
223
+ )
224
+
225
+
226
+ @configuration.command("create")
227
+ @click.argument("config_type")
228
+ @click.option(
229
+ "--data-file",
230
+ "-D",
231
+ "data_file",
232
+ required=True,
233
+ type=click.Path(exists=True, dir_okay=False, readable=True, path_type=Path),
234
+ help="JSON file containing the full configuration body to POST.",
235
+ )
236
+ @click.option("--branch", "-b", type=int, default=None, help="Branch ID (falls back to global -b)")
237
+ @pass_context
238
+ @require_auth
239
+ @restrict_in_restricted_mode("creates platform configurations")
240
+ def configuration_create(
241
+ ctx: DxsContext,
242
+ config_type: str,
243
+ data_file: Path,
244
+ branch: int | None,
245
+ ) -> None:
246
+ """Create a new platform configuration via POST with a body read from a file.
247
+
248
+ The body is read from disk (no shell escaping), so payloads with embedded
249
+ \\r\\n sequences, nested quotes, or large flow code blocks round-trip cleanly.
250
+
251
+ \b
252
+ Examples:
253
+ dxs configuration create grid -b 64 -D new_grid.json
254
+ dxs configuration create flow -b 64 -D fn_body.json
255
+ """
256
+ config_type = _validate_type(config_type)
257
+ branch_id = resolve_branch(ctx, branch, "DXS-CFG-010")
258
+
259
+ body = _load_body(data_file)
260
+ api_client = ApiClient()
261
+ path = ConfigurationEndpoints.create(branch_id, config_type)
262
+ response = api_client.post(path, data=body)
263
+
264
+ ctx.output(
265
+ single(
266
+ item={
267
+ "type": config_type,
268
+ "branch_id": branch_id,
269
+ "source_file": str(data_file),
270
+ "response": response,
271
+ },
272
+ semantic_key="configuration_create",
273
+ )
274
+ )
275
+
276
+
277
+ @configuration.command("upsert")
278
+ @click.argument("config_type")
279
+ @click.option(
280
+ "--data-file",
281
+ "-D",
282
+ "data_file",
283
+ required=True,
284
+ type=click.Path(exists=True, dir_okay=False, readable=True, path_type=Path),
285
+ help="JSON file containing the full configuration body.",
286
+ )
287
+ @click.option("--branch", "-b", type=int, default=None, help="Branch ID (falls back to global -b)")
288
+ @pass_context
289
+ @require_auth
290
+ @restrict_in_restricted_mode("creates or updates platform configurations")
291
+ @handle_errors
292
+ def configuration_upsert(
293
+ ctx: DxsContext,
294
+ config_type: str,
295
+ data_file: Path,
296
+ branch: int | None,
297
+ ) -> None:
298
+ """Create or update a platform configuration (orchestrated upsert).
299
+
300
+ Reads the configuration body from a JSON file, looks up the existing
301
+ config on the branch by referenceName, then either POSTs (create) or
302
+ locks+PUTs (update) atomically. Handles the Datex Studio source-control
303
+ lock protocol on the user's behalf — inherited configs are locked before
304
+ PUT, and locks are released best-effort if the PUT fails.
305
+
306
+ \b
307
+ Examples:
308
+ dxs configuration upsert datasource -b 64 -D ds_orders.json
309
+ dxs configuration upsert flow -b 64 -D fn_body.json
310
+ """
311
+ config_type = _validate_type(config_type)
312
+ branch_id = resolve_branch(ctx, branch, "DXS-CFG-010")
313
+
314
+ body = _load_body(data_file)
315
+
316
+ if not isinstance(body, dict):
317
+ raise ValidationError(
318
+ message=f"{data_file} must contain a JSON object at the top level.",
319
+ code="DXS-CFG-003",
320
+ suggestions=[
321
+ "Use 'dxs datasource generate' or 'dxs function generate' to produce a valid body."
322
+ ],
323
+ )
324
+
325
+ ref_name = body.get("referenceName")
326
+ if not ref_name or not is_valid_js_identifier(ref_name):
327
+ raise ValidationError(
328
+ message=(
329
+ f"{data_file} must contain a 'referenceName' that is a valid JavaScript identifier."
330
+ ),
331
+ code="DXS-CFG-004",
332
+ suggestions=[
333
+ "Use 'dxs datasource generate' or 'dxs function generate' to produce a valid file.",
334
+ ],
335
+ )
336
+
337
+ api_client = ApiClient()
338
+ response, action = upsert_config(api_client, branch_id, config_type, ref_name, body)
339
+
340
+ ctx.output(
341
+ single(
342
+ item={
343
+ "type": config_type,
344
+ "branch_id": branch_id,
345
+ "source_file": str(data_file),
346
+ "action": action,
347
+ "response": response,
348
+ },
349
+ semantic_key="configuration_upsert",
350
+ )
351
+ )
352
+
353
+
354
+ @configuration.command("validate")
355
+ @click.argument("config_type")
356
+ @click.option(
357
+ "--data-file",
358
+ "-D",
359
+ "data_file",
360
+ required=True,
361
+ type=click.Path(exists=True, dir_okay=False, readable=True, path_type=Path),
362
+ help="JSON file containing the configuration body to validate.",
363
+ )
364
+ @click.option("--branch", "-b", type=int, default=None, help="Branch ID (falls back to global -b)")
365
+ @pass_context
366
+ @require_auth
367
+ def configuration_validate(
368
+ ctx: DxsContext,
369
+ config_type: str,
370
+ data_file: Path,
371
+ branch: int | None,
372
+ ) -> None:
373
+ """Validate a platform configuration body against a branch.
374
+
375
+ Returns either {status: "valid"} or a list of validation_errors.
376
+
377
+ \b
378
+ Examples:
379
+ dxs configuration validate grid -b 64 -D grid.json
380
+ dxs configuration validate flow -b 64 -D fn_body.json
381
+ """
382
+ config_type = _validate_type(config_type)
383
+ branch_id = resolve_branch(ctx, branch, "DXS-CFG-010")
384
+
385
+ body = _load_body(data_file)
386
+ api_client = ApiClient()
387
+ path = ConfigurationEndpoints.validate_config(branch_id, config_type)
388
+ response = api_client.post(path, data=body)
389
+
390
+ errors = response if isinstance(response, list) else []
391
+ if not errors:
392
+ ctx.output(
393
+ single(
394
+ item={"status": "valid", "message": "No validation errors"},
395
+ semantic_key="validation_result",
396
+ )
397
+ )
398
+ else:
399
+ formatted = [
400
+ {"message": e.get("message", str(e)) if isinstance(e, dict) else str(e)}
401
+ for e in errors
402
+ ]
403
+ ctx.output(list_response(items=formatted, semantic_key="validation_errors"))
404
+
405
+
406
+ @configuration.command("contexts")
407
+ @click.argument("config_type")
408
+ @click.option(
409
+ "--data-file",
410
+ "-D",
411
+ "data_file",
412
+ required=True,
413
+ type=click.Path(exists=True, dir_okay=False, readable=True, path_type=Path),
414
+ help="JSON file containing the configuration body whose designer contexts you want.",
415
+ )
416
+ @click.option("--branch", "-b", type=int, default=None, help="Branch ID (falls back to global -b)")
417
+ @pass_context
418
+ @require_auth
419
+ def configuration_contexts(
420
+ ctx: DxsContext,
421
+ config_type: str,
422
+ data_file: Path,
423
+ branch: int | None,
424
+ ) -> None:
425
+ """Get designer contexts (Monaco-editor type defs) for a configuration body.
426
+
427
+ Returns the same shape the platform's Monaco editor uses for IntelliSense
428
+ on flow code, expressions, and bindings.
429
+
430
+ \b
431
+ Examples:
432
+ dxs configuration contexts flow -b 64 -D fn.json
433
+ dxs configuration contexts datasource -b 64 -D ds.json
434
+ """
435
+ config_type = _validate_type(config_type)
436
+ branch_id = resolve_branch(ctx, branch, "DXS-CFG-010")
437
+
438
+ body = _load_body(data_file)
439
+ api_client = ApiClient()
440
+ path = ConfigurationEndpoints.contexts(branch_id, config_type)
441
+ response = api_client.post(path, data=body)
442
+
443
+ ctx.output(single(item=response or {}, semantic_key="configuration_contexts"))
444
+
445
+
446
+ @configuration.command("list")
447
+ @click.argument("config_type")
448
+ @click.option("--branch", "-b", type=int, default=None, help="Branch ID (falls back to global -b)")
449
+ @pass_context
450
+ @require_auth
451
+ def configuration_list(
452
+ ctx: DxsContext,
453
+ config_type: str,
454
+ branch: int | None,
455
+ ) -> None:
456
+ """List configurations of a given type on a branch.
457
+
458
+ \b
459
+ Examples:
460
+ dxs configuration list hub -b 64
461
+ dxs configuration list flow -b 64
462
+ """
463
+ config_type = _validate_type(config_type)
464
+ branch_id = resolve_branch(ctx, branch, "DXS-CFG-010")
465
+
466
+ api_client = ApiClient()
467
+ path = ConfigurationEndpoints.list_all(branch_id, config_type)
468
+ body = api_client.get(path)
469
+
470
+ ctx.output(single(item=body, semantic_key="configurations"))
471
+
472
+
473
+ @configuration.command("delete")
474
+ @click.argument("config_type")
475
+ @click.argument("config_ref")
476
+ @click.option("--branch", "-b", type=int, default=None, help="Branch ID (falls back to global -b)")
477
+ @click.option("--yes", "-y", is_flag=True, help="Skip the confirmation prompt.")
478
+ @pass_context
479
+ @require_auth
480
+ @handle_errors
481
+ @restrict_in_restricted_mode("deletes platform configurations")
482
+ def configuration_delete(
483
+ ctx: DxsContext,
484
+ config_type: str,
485
+ config_ref: str,
486
+ branch: int | None,
487
+ yes: bool,
488
+ ) -> None:
489
+ """Delete a platform configuration by type and ID or reference name.
490
+
491
+ \b
492
+ Arguments:
493
+ CONFIG_TYPE Configuration type (e.g., hub, grid, form, editor, flow)
494
+ CONFIG_REF Numeric configuration ID, or the config's reference name.
495
+ An all-digit value is always treated as an ID.
496
+
497
+ \b
498
+ Examples:
499
+ dxs configuration delete grid 8642750 -b 64 --yes
500
+ dxs configuration delete grid my_grid -b 64 --yes
501
+ """
502
+ config_type = _validate_type(config_type)
503
+ branch_id = resolve_branch(ctx, branch, "DXS-CFG-010")
504
+
505
+ api_client = ApiClient()
506
+ if config_ref.isdigit():
507
+ config_id = int(config_ref)
508
+ label = str(config_id)
509
+ else:
510
+ resolved = resolve_config_by_reference(api_client, branch_id, config_type, config_ref)
511
+ config_id = resolved["id"]
512
+ label = f"{config_ref} (id {config_id})"
513
+
514
+ if not yes:
515
+ click.confirm(
516
+ f"Delete {config_type} configuration {label} on branch {branch_id}?",
517
+ abort=True,
518
+ )
519
+
520
+ path = ConfigurationEndpoints.delete(branch_id, config_type, config_id)
521
+ api_client.delete(path)
522
+
523
+ ctx.output(
524
+ single(
525
+ item={
526
+ "id": config_id,
527
+ "type": config_type,
528
+ "branch_id": branch_id,
529
+ "deleted": True,
530
+ },
531
+ semantic_key="configuration_delete",
532
+ )
533
+ )