datex-studio-cli 0.4.5__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.
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/PKG-INFO +1 -1
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/pyproject.toml +1 -1
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/__init__.py +1 -1
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/cli.py +4 -2
- datex_studio_cli-0.4.7/src/dxs/commands/configuration.py +533 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/commands/crm.py +601 -94
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/commands/datasource.py +41 -64
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/commands/function.py +1 -53
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/commands/report/api.py +7 -2
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/commands/report/create.py +30 -6
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/commands/report/folder.py +38 -5
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/commands/studio.py +159 -25
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/api/app_config.py +41 -1
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/api/endpoints.py +15 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/datasource/generator.py +81 -30
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/datasource/resolver.py +1 -1
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/dynamics/client.py +80 -12
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/report/engine.py +47 -9
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/report/preview_arjs.py +52 -7
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/utils/resolvers.py +60 -28
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/web/static/report-validate.html +18 -1
- datex_studio_cli-0.4.5/src/dxs/commands/configuration.py +0 -250
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/.gitignore +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/README.md +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/report-creator.skill +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/scripts/analyze_corpus.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/scripts/generate_rdlx_schema.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/__main__.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/commands/__init__.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/commands/api.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/commands/auth.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/commands/branch.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/commands/config.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/commands/devops.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/commands/document.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/commands/endpoint.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/commands/env.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/commands/explore.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/commands/marketplace.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/commands/odata.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/commands/organization.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/commands/proxy.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/commands/release_notes.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/commands/repo.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/commands/report/__init__.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/commands/report/add_cmds.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/commands/report/batch.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/commands/report/data.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/commands/report/dataset.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/commands/report/edit.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/commands/report/preview.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/commands/report/schema_cmds.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/commands/schema.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/commands/servicepack.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/commands/source.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/commands/telemetry.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/commands/user.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/context.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/__init__.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/api/__init__.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/api/client.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/api/metadata_models.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/api/models.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/auth/__init__.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/auth/decorators.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/auth/msal_client.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/auth/token_cache.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/cache.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/datasource/__init__.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/datasource/flow_generator.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/datasource/flow_models.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/datasource/models.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/datasource/parsers.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/datasource/type_def_parser.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/datasource/validator.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/designer/__init__.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/designer/flow_models.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/designer/models.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/designer/parsers.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/devops/__init__.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/devops/client.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/devops/helpers.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/devops/models.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/dynamics/__init__.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/dynamics/metadata_cache.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/footprint/__init__.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/footprint/client.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/footprint/edmx_parser.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/footprint/metadata.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/function/__init__.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/function/generator.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/function/models.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/function/validator.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/graph.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/output/__init__.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/output/csv_fmt.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/output/formatter.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/output/json_fmt.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/output/redaction.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/output/yaml_fmt.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/release_notes.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/responses.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/telemetry/__init__.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/telemetry/config.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/telemetry/identity.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/telemetry/recorder.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/telemetry/scrubber.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/core/telemetry/sender.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/models/__init__.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/report/__init__.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/report/datasource_binding.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/report/field_parser.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/report/folder.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/report/manifest.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/report/models.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/report/preview.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/report/schema.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/report/svg_renderer.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/report/templates/__init__.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/report/templates/bill_of_lading.rdlx-json +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/report/templates/shipping_label.rdlx-json +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/report/validate_arjs.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/report/validator.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/report/wrapper.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/utils/__init__.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/utils/click_options.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/utils/config.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/utils/errors.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/utils/filtering.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/utils/image.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/utils/paths.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/utils/responses.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/utils/restricted.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/utils/sorting.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/utils/update_check.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/web/__init__.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/web/app.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/web/design.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/web/proxy_app.py +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/web/static/404/index.html +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/web/static/404.html +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/web/static/_next/static/UgyAMtPjH-Pt0RYWOHzIT/_buildManifest.js +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/web/static/_next/static/UgyAMtPjH-Pt0RYWOHzIT/_ssgManifest.js +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/web/static/_next/static/chunks/0b24cca5-c1e1c8810348f107.js +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/web/static/_next/static/chunks/255-102f2e5b2e3dc2ef.js +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/web/static/_next/static/chunks/4bd1b696-c023c6e3521b1417.js +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/web/static/_next/static/chunks/538-84e2e111415f1fda.js +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/web/static/_next/static/chunks/697-0e000ab410d9f470.js +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/web/static/_next/static/chunks/871-1acacdb7b4022abf.js +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/web/static/_next/static/chunks/8b8f67fc-6295949a4b5485a4.js +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/web/static/_next/static/chunks/909-c88abba3cf0caec3.js +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/web/static/_next/static/chunks/app/_not-found/page-ea1be7001c230704.js +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/web/static/_next/static/chunks/app/design/capture/page-a5e129c2d223432c.js +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/web/static/_next/static/chunks/app/design/page-21ba66a3dd3b03f0.js +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/web/static/_next/static/chunks/app/layout-2cc6eac09e476c91.js +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/web/static/_next/static/chunks/app/page-20c358395882cdac.js +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/web/static/_next/static/chunks/framework-de98b93a850cfc71.js +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/web/static/_next/static/chunks/main-0f18f91200dac003.js +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/web/static/_next/static/chunks/main-app-b69998d8941231d8.js +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/web/static/_next/static/chunks/pages/_app-7d307437aca18ad4.js +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/web/static/_next/static/chunks/pages/_error-cb2a52f75f2162e2.js +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/web/static/_next/static/chunks/polyfills-42372ed130431b0a.js +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/web/static/_next/static/chunks/webpack-2b297ada5306c17f.js +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/web/static/_next/static/css/360c657de5e04df8.css +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/web/static/design/capture/index.html +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/web/static/design/capture/index.txt +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/web/static/design/index.html +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/web/static/design/index.txt +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/web/static/index.html +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/web/static/index.txt +0 -0
- {datex_studio_cli-0.4.5 → datex_studio_cli-0.4.7}/src/dxs/web/static/render-cli.js +0 -0
- {datex_studio_cli-0.4.5 → 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.
|
|
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
|
|
@@ -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
|
+
)
|