datex-studio-cli 0.4.11__tar.gz → 0.4.13__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.11 → datex_studio_cli-0.4.13}/.gitignore +3 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/PKG-INFO +94 -4
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/README.md +93 -3
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/pyproject.toml +2 -1
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/__init__.py +1 -1
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/cli.py +50 -1
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/commands/auth.py +34 -19
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/commands/branch.py +83 -11
- datex_studio_cli-0.4.13/src/dxs/commands/cascade.py +701 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/commands/configuration.py +31 -3
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/commands/crm.py +384 -50
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/commands/devops.py +64 -11
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/commands/marketplace.py +36 -18
- datex_studio_cli-0.4.13/src/dxs/commands/ng/__init__.py +44 -0
- datex_studio_cli-0.4.13/src/dxs/commands/ng/_common.py +37 -0
- datex_studio_cli-0.4.13/src/dxs/commands/ng/api.py +149 -0
- datex_studio_cli-0.4.13/src/dxs/commands/ng/create.py +82 -0
- datex_studio_cli-0.4.13/src/dxs/commands/ng/data.py +222 -0
- datex_studio_cli-0.4.13/src/dxs/commands/ng/pack.py +63 -0
- datex_studio_cli-0.4.13/src/dxs/commands/ng/preview.py +384 -0
- datex_studio_cli-0.4.13/src/dxs/commands/reference.py +192 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/commands/repo.py +6 -6
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/commands/report/api.py +8 -6
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/commands/report/folder.py +5 -2
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/commands/report/preview.py +2 -2
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/commands/source.py +66 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/api/app_config.py +1 -17
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/api/client.py +18 -10
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/api/endpoints.py +42 -5
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/api/models.py +33 -7
- datex_studio_cli-0.4.13/src/dxs/core/api/reference_graph.py +132 -0
- datex_studio_cli-0.4.13/src/dxs/core/auth/datex_tenant.py +265 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/auth/msal_client.py +13 -3
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/datasource/parsers.py +2 -5
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/datasource/resolver.py +4 -8
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/devops/client.py +76 -68
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/dynamics/client.py +173 -111
- datex_studio_cli-0.4.13/src/dxs/ng/__init__.py +7 -0
- datex_studio_cli-0.4.13/src/dxs/ng/folder.py +256 -0
- datex_studio_cli-0.4.13/src/dxs/ng/manifest.py +127 -0
- datex_studio_cli-0.4.13/src/dxs/ng/mocks.py +142 -0
- datex_studio_cli-0.4.13/src/dxs/ng/preview.py +79 -0
- datex_studio_cli-0.4.13/src/dxs/ng/scaffold.py +88 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/report/datasource_binding.py +2 -5
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/report/folder.py +2 -6
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/report/preview_arjs.py +2 -2
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/utils/config.py +8 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/utils/resolvers.py +119 -17
- datex_studio_cli-0.4.13/src/dxs/utils/versioning.py +22 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/report-creator.skill +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/scripts/analyze_corpus.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/scripts/generate_rdlx_schema.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/__main__.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/commands/__init__.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/commands/api.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/commands/config.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/commands/datasource.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/commands/document.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/commands/endpoint.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/commands/env.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/commands/explore.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/commands/function.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/commands/init.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/commands/odata.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/commands/organization.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/commands/proxy.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/commands/release_notes.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/commands/report/__init__.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/commands/report/add_cmds.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/commands/report/batch.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/commands/report/create.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/commands/report/data.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/commands/report/dataset.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/commands/report/edit.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/commands/report/schema_cmds.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/commands/schema.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/commands/servicepack.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/commands/studio.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/commands/telemetry.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/commands/user.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/context.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/__init__.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/api/__init__.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/api/metadata_models.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/auth/__init__.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/auth/decorators.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/auth/token_cache.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/cache.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/datasource/__init__.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/datasource/flow_generator.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/datasource/flow_models.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/datasource/generator.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/datasource/models.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/datasource/type_def_parser.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/datasource/validator.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/designer/__init__.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/designer/flow_models.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/designer/models.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/designer/parsers.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/devops/__init__.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/devops/helpers.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/devops/models.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/dynamics/__init__.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/dynamics/metadata_cache.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/footprint/__init__.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/footprint/client.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/footprint/edmx_parser.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/footprint/metadata.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/function/__init__.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/function/generator.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/function/models.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/function/validator.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/graph.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/onboarding.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/output/__init__.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/output/csv_fmt.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/output/formatter.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/output/json_fmt.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/output/redaction.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/output/yaml_fmt.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/release_notes.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/responses.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/telemetry/__init__.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/telemetry/config.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/telemetry/identity.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/telemetry/recorder.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/telemetry/scrubber.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/core/telemetry/sender.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/models/__init__.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/py.typed +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/report/__init__.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/report/engine.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/report/field_parser.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/report/manifest.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/report/models.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/report/preview.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/report/schema.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/report/svg_renderer.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/report/templates/__init__.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/report/templates/bill_of_lading.rdlx-json +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/report/templates/shipping_label.rdlx-json +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/report/validate_arjs.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/report/validator.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/report/wrapper.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/utils/__init__.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/utils/click_options.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/utils/clipboard.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/utils/errors.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/utils/filtering.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/utils/image.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/utils/paths.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/utils/responses.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/utils/restricted.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/utils/sorting.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/utils/update_check.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/web/__init__.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/web/app.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/web/design.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/web/proxy_app.py +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/web/static/404/index.html +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/web/static/404.html +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/web/static/_next/static/UgyAMtPjH-Pt0RYWOHzIT/_buildManifest.js +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/web/static/_next/static/UgyAMtPjH-Pt0RYWOHzIT/_ssgManifest.js +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/web/static/_next/static/chunks/0b24cca5-c1e1c8810348f107.js +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/web/static/_next/static/chunks/255-102f2e5b2e3dc2ef.js +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/web/static/_next/static/chunks/4bd1b696-c023c6e3521b1417.js +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/web/static/_next/static/chunks/538-84e2e111415f1fda.js +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/web/static/_next/static/chunks/697-0e000ab410d9f470.js +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/web/static/_next/static/chunks/871-1acacdb7b4022abf.js +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/web/static/_next/static/chunks/8b8f67fc-6295949a4b5485a4.js +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/web/static/_next/static/chunks/909-c88abba3cf0caec3.js +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/web/static/_next/static/chunks/app/_not-found/page-ea1be7001c230704.js +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/web/static/_next/static/chunks/app/design/capture/page-a5e129c2d223432c.js +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/web/static/_next/static/chunks/app/design/page-21ba66a3dd3b03f0.js +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/web/static/_next/static/chunks/app/layout-2cc6eac09e476c91.js +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/web/static/_next/static/chunks/app/page-20c358395882cdac.js +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/web/static/_next/static/chunks/framework-de98b93a850cfc71.js +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/web/static/_next/static/chunks/main-0f18f91200dac003.js +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/web/static/_next/static/chunks/main-app-b69998d8941231d8.js +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/web/static/_next/static/chunks/pages/_app-7d307437aca18ad4.js +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/web/static/_next/static/chunks/pages/_error-cb2a52f75f2162e2.js +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/web/static/_next/static/chunks/polyfills-42372ed130431b0a.js +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/web/static/_next/static/chunks/webpack-2b297ada5306c17f.js +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/web/static/_next/static/css/360c657de5e04df8.css +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/web/static/design/capture/index.html +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/web/static/design/capture/index.txt +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/web/static/design/index.html +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/web/static/design/index.txt +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/web/static/index.html +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/web/static/index.txt +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/web/static/render-cli.js +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/web/static/report-preview.html +0 -0
- {datex_studio_cli-0.4.11 → datex_studio_cli-0.4.13}/src/dxs/web/static/report-validate.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.13
|
|
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
|
|
@@ -247,6 +247,7 @@ Direct commands on the `source` group:
|
|
|
247
247
|
| `locks` | Show current lock status |
|
|
248
248
|
| `deps <ref>` | Show configuration dependencies |
|
|
249
249
|
| `deps-diff` | Show dependency changes between versions |
|
|
250
|
+
| `referenced-from <pkg>` | List packages/apps that reference a package |
|
|
250
251
|
| `workitems` | Extract work items from commit messages |
|
|
251
252
|
| `compare` | Compare two branches |
|
|
252
253
|
| `graph` | Show dependency graph |
|
|
@@ -278,7 +279,8 @@ dxs source compare --source 100 --target 200
|
|
|
278
279
|
| `show <id>` | Show branch details |
|
|
279
280
|
| `create` | Create a new feature branch |
|
|
280
281
|
| `delete <id>` | Delete a feature branch |
|
|
281
|
-
| `
|
|
282
|
+
| `commit <id>` | Commit (merge) a feature branch into its Main branch |
|
|
283
|
+
| `publish <id>` | Publish branch to marketplace (`--notes` is **required**) |
|
|
282
284
|
| `baseline <id>` | Find baseline (previous release) |
|
|
283
285
|
| `search <query>` | Search branches by name |
|
|
284
286
|
| `roles <id>` | Show branch roles |
|
|
@@ -305,6 +307,83 @@ dxs source branch list --repo 10 --with-changes
|
|
|
305
307
|
dxs source branch list --repo 10 --sort modified --desc
|
|
306
308
|
```
|
|
307
309
|
|
|
310
|
+
### Package References (`dxs source reference`)
|
|
311
|
+
|
|
312
|
+
| Command | Description |
|
|
313
|
+
|---------|-------------|
|
|
314
|
+
| `set` | Re-pin a direct package reference and rebuild transitive references |
|
|
315
|
+
|
|
316
|
+
```bash
|
|
317
|
+
# Pin Module1 to a newly published version on feature branch 3101
|
|
318
|
+
dxs source reference set -b 3101 -p Module1 -v 20260714.1000
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
Rebuilds the branch's flattened reference list after the bump and refuses the
|
|
322
|
+
write if the result would contain a version conflict (the same package pinned at
|
|
323
|
+
two versions) or a circular reference.
|
|
324
|
+
|
|
325
|
+
### Package Cascade (`dxs source cascade`)
|
|
326
|
+
|
|
327
|
+
When a package is republished, every package that references it stays pinned to
|
|
328
|
+
the old version until it is re-pinned and republished itself. The cascade
|
|
329
|
+
automates that fan-out.
|
|
330
|
+
|
|
331
|
+
| Command | Description |
|
|
332
|
+
|---------|-------------|
|
|
333
|
+
| `plan` | Compute the ordered set of packages to re-pin + republish |
|
|
334
|
+
| `run` | Execute a plan bottom-up (branch → re-pin → commit → publish) |
|
|
335
|
+
|
|
336
|
+
```bash
|
|
337
|
+
# 1. Plan the cascade from a package you just published
|
|
338
|
+
dxs source cascade plan -p Module1 -v 20260714.1000 -O json > plan.json
|
|
339
|
+
|
|
340
|
+
# 2. Review what it would do — mutates nothing
|
|
341
|
+
dxs source cascade run --plan plan.json --dry-run
|
|
342
|
+
|
|
343
|
+
# 3. Execute
|
|
344
|
+
dxs source cascade run --plan plan.json
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
`plan` walks reverse-references from the origin package and emits update nodes
|
|
348
|
+
grouped into topological levels, plus a `staleApplications` list — applications
|
|
349
|
+
that consume an affected package but cannot be cascaded automatically.
|
|
350
|
+
|
|
351
|
+
- `--org` scopes traversal to a single organization. **Omit it and the cascade
|
|
352
|
+
spans consumers across all organizations**, which is rarely what you want.
|
|
353
|
+
- `--max-depth` limits how far the traversal follows the reference chain.
|
|
354
|
+
|
|
355
|
+
`run` executes each level bottom-up, feeding each package's newly published
|
|
356
|
+
version forward to its dependents.
|
|
357
|
+
|
|
358
|
+
Before mutating anything it applies the same guardrails as `branch publish`:
|
|
359
|
+
each node's Main branch is resolved to its owning organization and checked
|
|
360
|
+
against the current identity (once per distinct organization), then the run is
|
|
361
|
+
confirmed. Each re-pinned feature branch is validated before it is committed, so
|
|
362
|
+
a broken reference set never reaches Main or the marketplace.
|
|
363
|
+
|
|
364
|
+
- `--dry-run` prints the resolved execution order and mutates nothing.
|
|
365
|
+
- `--yes` / `-y` skips the confirmation prompt — use this for unattended runs.
|
|
366
|
+
Branch validation still runs.
|
|
367
|
+
- `--force` / `-f` skips both the confirmation prompt and branch validation.
|
|
368
|
+
- `--select` restricts the run to named packages (repeatable). Deselecting an
|
|
369
|
+
intermediate dependency will fail the run, since its dependents need the
|
|
370
|
+
version it would have produced.
|
|
371
|
+
- `--release-notes` sets the notes for every republish; otherwise a summary of
|
|
372
|
+
the re-pins is used.
|
|
373
|
+
|
|
374
|
+
A node whose dependencies are all already at their target version is skipped
|
|
375
|
+
rather than republished for zero change, and its dependents treat it as a no-op
|
|
376
|
+
instead of failing.
|
|
377
|
+
|
|
378
|
+
Publishing can block on a build, so the publish step uses the longer
|
|
379
|
+
`publish_timeout` setting (default 300s) rather than `api_timeout`. If that call
|
|
380
|
+
still times out, the version is confirmed by looking up the exact
|
|
381
|
+
`(package, version)` pair in the marketplace — the record is committed before the
|
|
382
|
+
build runs, so a timed-out publish has usually still landed.
|
|
383
|
+
|
|
384
|
+
`cascade run` and `reference set` are both blocked when
|
|
385
|
+
`DXS_RESTRICTED_MODE=true`.
|
|
386
|
+
|
|
308
387
|
### Repository Management (`dxs source repo`)
|
|
309
388
|
|
|
310
389
|
| Command | Description |
|
|
@@ -608,11 +687,22 @@ dxs odata execute -c 1 -q "Products?\$select=Id,Name,Price&\$top=10"
|
|
|
608
687
|
|
|
609
688
|
| Command | Description |
|
|
610
689
|
|---------|-------------|
|
|
611
|
-
| `list` | List marketplace
|
|
690
|
+
| `list` | List marketplace packages available to your org |
|
|
612
691
|
| `show <id>` | Show application details |
|
|
613
692
|
| `versions <id>` | List published versions |
|
|
614
693
|
| `version <id>` | Show version details |
|
|
615
|
-
| `search <query>` | Search
|
|
694
|
+
| `search <query>` | Search available packages by name/description |
|
|
695
|
+
|
|
696
|
+
`list` and `search` mirror the Manager > Marketplace screen: they show packages
|
|
697
|
+
available to a consumer organization, each with an `included` flag indicating
|
|
698
|
+
whether that org already has access.
|
|
699
|
+
|
|
700
|
+
- `--type` selects the marketplace application type, defaulting to
|
|
701
|
+
`componentmodule`. Other types (`web`, `mobile`, `api`, `portal`,
|
|
702
|
+
`footprintapi`, `taskscheduler`) are accepted but are not what the Marketplace
|
|
703
|
+
screen shows.
|
|
704
|
+
- `--org` is the *consumer* organization being browsed on behalf of, not a
|
|
705
|
+
result filter. Omit it to browse as your own organization.
|
|
616
706
|
|
|
617
707
|
### Azure DevOps (`dxs devops`)
|
|
618
708
|
|
|
@@ -194,6 +194,7 @@ Direct commands on the `source` group:
|
|
|
194
194
|
| `locks` | Show current lock status |
|
|
195
195
|
| `deps <ref>` | Show configuration dependencies |
|
|
196
196
|
| `deps-diff` | Show dependency changes between versions |
|
|
197
|
+
| `referenced-from <pkg>` | List packages/apps that reference a package |
|
|
197
198
|
| `workitems` | Extract work items from commit messages |
|
|
198
199
|
| `compare` | Compare two branches |
|
|
199
200
|
| `graph` | Show dependency graph |
|
|
@@ -225,7 +226,8 @@ dxs source compare --source 100 --target 200
|
|
|
225
226
|
| `show <id>` | Show branch details |
|
|
226
227
|
| `create` | Create a new feature branch |
|
|
227
228
|
| `delete <id>` | Delete a feature branch |
|
|
228
|
-
| `
|
|
229
|
+
| `commit <id>` | Commit (merge) a feature branch into its Main branch |
|
|
230
|
+
| `publish <id>` | Publish branch to marketplace (`--notes` is **required**) |
|
|
229
231
|
| `baseline <id>` | Find baseline (previous release) |
|
|
230
232
|
| `search <query>` | Search branches by name |
|
|
231
233
|
| `roles <id>` | Show branch roles |
|
|
@@ -252,6 +254,83 @@ dxs source branch list --repo 10 --with-changes
|
|
|
252
254
|
dxs source branch list --repo 10 --sort modified --desc
|
|
253
255
|
```
|
|
254
256
|
|
|
257
|
+
### Package References (`dxs source reference`)
|
|
258
|
+
|
|
259
|
+
| Command | Description |
|
|
260
|
+
|---------|-------------|
|
|
261
|
+
| `set` | Re-pin a direct package reference and rebuild transitive references |
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
# Pin Module1 to a newly published version on feature branch 3101
|
|
265
|
+
dxs source reference set -b 3101 -p Module1 -v 20260714.1000
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
Rebuilds the branch's flattened reference list after the bump and refuses the
|
|
269
|
+
write if the result would contain a version conflict (the same package pinned at
|
|
270
|
+
two versions) or a circular reference.
|
|
271
|
+
|
|
272
|
+
### Package Cascade (`dxs source cascade`)
|
|
273
|
+
|
|
274
|
+
When a package is republished, every package that references it stays pinned to
|
|
275
|
+
the old version until it is re-pinned and republished itself. The cascade
|
|
276
|
+
automates that fan-out.
|
|
277
|
+
|
|
278
|
+
| Command | Description |
|
|
279
|
+
|---------|-------------|
|
|
280
|
+
| `plan` | Compute the ordered set of packages to re-pin + republish |
|
|
281
|
+
| `run` | Execute a plan bottom-up (branch → re-pin → commit → publish) |
|
|
282
|
+
|
|
283
|
+
```bash
|
|
284
|
+
# 1. Plan the cascade from a package you just published
|
|
285
|
+
dxs source cascade plan -p Module1 -v 20260714.1000 -O json > plan.json
|
|
286
|
+
|
|
287
|
+
# 2. Review what it would do — mutates nothing
|
|
288
|
+
dxs source cascade run --plan plan.json --dry-run
|
|
289
|
+
|
|
290
|
+
# 3. Execute
|
|
291
|
+
dxs source cascade run --plan plan.json
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
`plan` walks reverse-references from the origin package and emits update nodes
|
|
295
|
+
grouped into topological levels, plus a `staleApplications` list — applications
|
|
296
|
+
that consume an affected package but cannot be cascaded automatically.
|
|
297
|
+
|
|
298
|
+
- `--org` scopes traversal to a single organization. **Omit it and the cascade
|
|
299
|
+
spans consumers across all organizations**, which is rarely what you want.
|
|
300
|
+
- `--max-depth` limits how far the traversal follows the reference chain.
|
|
301
|
+
|
|
302
|
+
`run` executes each level bottom-up, feeding each package's newly published
|
|
303
|
+
version forward to its dependents.
|
|
304
|
+
|
|
305
|
+
Before mutating anything it applies the same guardrails as `branch publish`:
|
|
306
|
+
each node's Main branch is resolved to its owning organization and checked
|
|
307
|
+
against the current identity (once per distinct organization), then the run is
|
|
308
|
+
confirmed. Each re-pinned feature branch is validated before it is committed, so
|
|
309
|
+
a broken reference set never reaches Main or the marketplace.
|
|
310
|
+
|
|
311
|
+
- `--dry-run` prints the resolved execution order and mutates nothing.
|
|
312
|
+
- `--yes` / `-y` skips the confirmation prompt — use this for unattended runs.
|
|
313
|
+
Branch validation still runs.
|
|
314
|
+
- `--force` / `-f` skips both the confirmation prompt and branch validation.
|
|
315
|
+
- `--select` restricts the run to named packages (repeatable). Deselecting an
|
|
316
|
+
intermediate dependency will fail the run, since its dependents need the
|
|
317
|
+
version it would have produced.
|
|
318
|
+
- `--release-notes` sets the notes for every republish; otherwise a summary of
|
|
319
|
+
the re-pins is used.
|
|
320
|
+
|
|
321
|
+
A node whose dependencies are all already at their target version is skipped
|
|
322
|
+
rather than republished for zero change, and its dependents treat it as a no-op
|
|
323
|
+
instead of failing.
|
|
324
|
+
|
|
325
|
+
Publishing can block on a build, so the publish step uses the longer
|
|
326
|
+
`publish_timeout` setting (default 300s) rather than `api_timeout`. If that call
|
|
327
|
+
still times out, the version is confirmed by looking up the exact
|
|
328
|
+
`(package, version)` pair in the marketplace — the record is committed before the
|
|
329
|
+
build runs, so a timed-out publish has usually still landed.
|
|
330
|
+
|
|
331
|
+
`cascade run` and `reference set` are both blocked when
|
|
332
|
+
`DXS_RESTRICTED_MODE=true`.
|
|
333
|
+
|
|
255
334
|
### Repository Management (`dxs source repo`)
|
|
256
335
|
|
|
257
336
|
| Command | Description |
|
|
@@ -555,11 +634,22 @@ dxs odata execute -c 1 -q "Products?\$select=Id,Name,Price&\$top=10"
|
|
|
555
634
|
|
|
556
635
|
| Command | Description |
|
|
557
636
|
|---------|-------------|
|
|
558
|
-
| `list` | List marketplace
|
|
637
|
+
| `list` | List marketplace packages available to your org |
|
|
559
638
|
| `show <id>` | Show application details |
|
|
560
639
|
| `versions <id>` | List published versions |
|
|
561
640
|
| `version <id>` | Show version details |
|
|
562
|
-
| `search <query>` | Search
|
|
641
|
+
| `search <query>` | Search available packages by name/description |
|
|
642
|
+
|
|
643
|
+
`list` and `search` mirror the Manager > Marketplace screen: they show packages
|
|
644
|
+
available to a consumer organization, each with an `included` flag indicating
|
|
645
|
+
whether that org already has access.
|
|
646
|
+
|
|
647
|
+
- `--type` selects the marketplace application type, defaulting to
|
|
648
|
+
`componentmodule`. Other types (`web`, `mobile`, `api`, `portal`,
|
|
649
|
+
`footprintapi`, `taskscheduler`) are accepted but are not what the Marketplace
|
|
650
|
+
screen shows.
|
|
651
|
+
- `--org` is the *consumer* organization being browsed on behalf of, not a
|
|
652
|
+
result filter. Omit it to browse as your own organization.
|
|
563
653
|
|
|
564
654
|
### Azure DevOps (`dxs devops`)
|
|
565
655
|
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "datex-studio-cli"
|
|
7
|
-
version = "0.4.
|
|
7
|
+
version = "0.4.13"
|
|
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"
|
|
@@ -152,6 +152,7 @@ python_functions = ["test_*"]
|
|
|
152
152
|
addopts = "-v --tb=short"
|
|
153
153
|
markers = [
|
|
154
154
|
"fidelity: cross-engine SSIM fidelity tests (require agent-browser + ARJS)",
|
|
155
|
+
"internal_commands_gated: exercise the devops/crm visibility gate (no DXS_INTERNAL_COMMANDS override)",
|
|
155
156
|
]
|
|
156
157
|
|
|
157
158
|
[tool.coverage.run]
|
|
@@ -8,6 +8,7 @@ import click
|
|
|
8
8
|
|
|
9
9
|
from dxs import __app_name__, __version__
|
|
10
10
|
from dxs.context import DxsContext, pass_context # re-exported for backward compat
|
|
11
|
+
from dxs.core.auth.datex_tenant import DATEX_INTERNAL_COMMANDS, internal_commands_available
|
|
11
12
|
from dxs.core.output import OutputFormat, format_error
|
|
12
13
|
from dxs.core.output.redaction import (
|
|
13
14
|
AUTHOR_VERBOSE_FIELDS as _AUTHOR_VERBOSE_FIELDS, # noqa: F401 — re-exported
|
|
@@ -69,6 +70,29 @@ def _stdout_is_pipe() -> bool:
|
|
|
69
70
|
return False
|
|
70
71
|
|
|
71
72
|
|
|
73
|
+
def _ensure_utf8_streams() -> None:
|
|
74
|
+
"""Force stdout/stderr to UTF-8 so non-ASCII output never crashes the CLI.
|
|
75
|
+
|
|
76
|
+
On Windows a piped or redirected stream defaults to the locale encoding
|
|
77
|
+
(typically cp1252), which cannot represent characters such as U+2192 (the
|
|
78
|
+
arrow used in help text like ``dxs source cascade -h`` and in ``cascade
|
|
79
|
+
run`` progress logs). Writing them raises ``UnicodeEncodeError`` and aborts
|
|
80
|
+
the command. Reconfiguring to UTF-8 at entry is lossless and idempotent.
|
|
81
|
+
|
|
82
|
+
Streams that do not support reconfiguration (already detached, or a test
|
|
83
|
+
double) are left untouched.
|
|
84
|
+
"""
|
|
85
|
+
for stream in (sys.stdout, sys.stderr):
|
|
86
|
+
reconfigure = getattr(stream, "reconfigure", None)
|
|
87
|
+
if reconfigure is None:
|
|
88
|
+
continue
|
|
89
|
+
try:
|
|
90
|
+
reconfigure(encoding="utf-8")
|
|
91
|
+
except (ValueError, OSError):
|
|
92
|
+
# Reconfiguration is unsupported for this stream; leave it as-is.
|
|
93
|
+
pass
|
|
94
|
+
|
|
95
|
+
|
|
72
96
|
# Global options shared across all commands
|
|
73
97
|
CONTEXT_SETTINGS = {
|
|
74
98
|
"help_option_names": ["-h", "--help"],
|
|
@@ -77,7 +101,29 @@ CONTEXT_SETTINGS = {
|
|
|
77
101
|
|
|
78
102
|
|
|
79
103
|
class DxsGroup(click.Group):
|
|
80
|
-
"""Custom Group that shows global options in subcommand help.
|
|
104
|
+
"""Custom Group that shows global options in subcommand help.
|
|
105
|
+
|
|
106
|
+
Also gates the Datex-internal command groups (``devops``, ``crm``). The gate
|
|
107
|
+
is applied at lookup time rather than at registration so it reflects the
|
|
108
|
+
identity cache as of *this* invocation — registration happens once at import.
|
|
109
|
+
"""
|
|
110
|
+
|
|
111
|
+
def _is_gated(self, cmd_name: str) -> bool:
|
|
112
|
+
"""Whether ``cmd_name`` is Datex-internal and unavailable to this user."""
|
|
113
|
+
return cmd_name in DATEX_INTERNAL_COMMANDS and not internal_commands_available()
|
|
114
|
+
|
|
115
|
+
def list_commands(self, ctx: click.Context) -> list[str]:
|
|
116
|
+
"""List visible subcommands, omitting unavailable Datex-internal groups."""
|
|
117
|
+
return [name for name in super().list_commands(ctx) if not self._is_gated(name)]
|
|
118
|
+
|
|
119
|
+
def get_command(self, ctx: click.Context, cmd_name: str) -> click.Command | None:
|
|
120
|
+
"""Resolve a subcommand, refusing unavailable Datex-internal groups."""
|
|
121
|
+
if self._is_gated(cmd_name):
|
|
122
|
+
ctx.fail(
|
|
123
|
+
f"'{cmd_name}' is a Datex-internal command group and requires a "
|
|
124
|
+
"Datex tenant identity. Run 'dxs auth login' with your Datex account."
|
|
125
|
+
)
|
|
126
|
+
return super().get_command(ctx, cmd_name)
|
|
81
127
|
|
|
82
128
|
def format_options(self, ctx: click.Context, formatter: click.HelpFormatter) -> None:
|
|
83
129
|
"""Write options to the formatter, including global options."""
|
|
@@ -475,6 +521,7 @@ def register_commands() -> None:
|
|
|
475
521
|
function,
|
|
476
522
|
init,
|
|
477
523
|
marketplace,
|
|
524
|
+
ng,
|
|
478
525
|
odata,
|
|
479
526
|
organization,
|
|
480
527
|
proxy,
|
|
@@ -497,6 +544,7 @@ def register_commands() -> None:
|
|
|
497
544
|
cli.add_command(env.env)
|
|
498
545
|
cli.add_command(function.function)
|
|
499
546
|
cli.add_command(marketplace.marketplace)
|
|
547
|
+
cli.add_command(ng.ng)
|
|
500
548
|
cli.add_command(odata.odata)
|
|
501
549
|
cli.add_command(organization.organization)
|
|
502
550
|
cli.add_command(proxy.proxy)
|
|
@@ -609,6 +657,7 @@ register_commands()
|
|
|
609
657
|
# Main entry point
|
|
610
658
|
def main() -> None:
|
|
611
659
|
"""Main entry point for the CLI."""
|
|
660
|
+
_ensure_utf8_streams()
|
|
612
661
|
try:
|
|
613
662
|
try:
|
|
614
663
|
cli()
|
|
@@ -8,6 +8,7 @@ import click
|
|
|
8
8
|
|
|
9
9
|
from dxs.context import DxsContext, pass_context
|
|
10
10
|
from dxs.core.auth import MSALClient, MultiIdentityTokenCache
|
|
11
|
+
from dxs.core.auth.datex_tenant import claims_are_datex, is_datex_identity
|
|
11
12
|
from dxs.core.auth.decorators import get_access_token
|
|
12
13
|
from dxs.core.auth.token_cache import CachedIdentity, get_identity_override
|
|
13
14
|
from dxs.core.footprint import get_footprint_token
|
|
@@ -78,23 +79,33 @@ def run_standard_device_login(
|
|
|
78
79
|
consent_cb = on_additional_consent_needed or _on_consent
|
|
79
80
|
|
|
80
81
|
ctx.log("Initiating device code authentication...")
|
|
82
|
+
additional_scope_sets: Any
|
|
81
83
|
if tenant_id is not None:
|
|
82
84
|
client = MSALClient.for_tenant(tenant_id, scopes=settings.azure_scopes)
|
|
83
85
|
# External tenants only need Studio API + Footprint; DevOps/CRM are not relevant.
|
|
84
86
|
additional_scope_sets = [[settings.footprint_scope]]
|
|
85
87
|
else:
|
|
86
88
|
client = MSALClient(scopes=settings.azure_scopes)
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
89
|
+
|
|
90
|
+
def additional_scope_sets(token_response: dict[str, Any]) -> list[list[str]]:
|
|
91
|
+
"""Choose consent scopes from the claims of whoever just signed in.
|
|
92
|
+
|
|
93
|
+
The home-tenant path is also what customers hit before their own
|
|
94
|
+
tenant is known, so DevOps/CRM consent is requested only for Datex
|
|
95
|
+
staff — a customer must never be prompted for Datex-internal
|
|
96
|
+
resources by name.
|
|
97
|
+
"""
|
|
98
|
+
internal = (
|
|
99
|
+
[
|
|
100
|
+
settings.azure_devops_scopes,
|
|
101
|
+
settings.dynamics_crm_scopes,
|
|
102
|
+
settings.dynamics_crm_admin_scopes,
|
|
103
|
+
settings.data_export_service_scopes,
|
|
104
|
+
]
|
|
105
|
+
if claims_are_datex(token_response.get("id_token_claims") or {})
|
|
106
|
+
else []
|
|
107
|
+
)
|
|
108
|
+
return [scopes for scopes in [*internal, [settings.footprint_scope]] if scopes]
|
|
98
109
|
|
|
99
110
|
result = client.authenticate_device_code_multi_resource(
|
|
100
111
|
primary_scopes=settings.azure_scopes,
|
|
@@ -638,17 +649,21 @@ def status(ctx: DxsContext) -> None:
|
|
|
638
649
|
"name": "Datex Studio API",
|
|
639
650
|
"scopes": settings.azure_scopes,
|
|
640
651
|
},
|
|
641
|
-
"azure_devops": {
|
|
642
|
-
"name": "Azure DevOps API",
|
|
643
|
-
"scopes": settings.azure_devops_scopes,
|
|
644
|
-
},
|
|
645
652
|
}
|
|
646
653
|
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
654
|
+
# DevOps and CRM are Datex-internal. Probing them with a customer identity
|
|
655
|
+
# only ever yields noise, so omit those rows entirely unless the identity
|
|
656
|
+
# being reported is a Datex one.
|
|
657
|
+
if is_datex_identity(active_identity):
|
|
658
|
+
resources["azure_devops"] = {
|
|
659
|
+
"name": "Azure DevOps API",
|
|
660
|
+
"scopes": settings.azure_devops_scopes,
|
|
651
661
|
}
|
|
662
|
+
if settings.dynamics_crm_scopes:
|
|
663
|
+
resources["dynamics_crm"] = {
|
|
664
|
+
"name": "Dynamics CRM API",
|
|
665
|
+
"scopes": settings.dynamics_crm_scopes,
|
|
666
|
+
}
|
|
652
667
|
|
|
653
668
|
resources["footprint"] = {
|
|
654
669
|
"name": "Footprint API",
|
|
@@ -38,6 +38,7 @@ from dxs.utils import (
|
|
|
38
38
|
from dxs.utils.errors import ValidationError
|
|
39
39
|
from dxs.utils.responses import list_response, search_response, single
|
|
40
40
|
from dxs.utils.restricted import restrict_in_restricted_mode
|
|
41
|
+
from dxs.utils.versioning import generate_version
|
|
41
42
|
|
|
42
43
|
|
|
43
44
|
def enrich_branch_with_status(branch: dict[str, Any]) -> dict[str, Any]:
|
|
@@ -1278,8 +1279,8 @@ def create(
|
|
|
1278
1279
|
@click.option(
|
|
1279
1280
|
"--notes",
|
|
1280
1281
|
"-n",
|
|
1281
|
-
|
|
1282
|
-
help="Release notes describing the changes",
|
|
1282
|
+
required=True,
|
|
1283
|
+
help="Release notes describing the changes (required)",
|
|
1283
1284
|
)
|
|
1284
1285
|
@click.option(
|
|
1285
1286
|
"--force",
|
|
@@ -1295,7 +1296,7 @@ def publish(
|
|
|
1295
1296
|
ctx: DxsContext,
|
|
1296
1297
|
branch_id: int,
|
|
1297
1298
|
version: str | None,
|
|
1298
|
-
notes: str
|
|
1299
|
+
notes: str,
|
|
1299
1300
|
force: bool,
|
|
1300
1301
|
) -> None:
|
|
1301
1302
|
"""Publish a branch to the marketplace.
|
|
@@ -1310,14 +1311,13 @@ def publish(
|
|
|
1310
1311
|
\b
|
|
1311
1312
|
Options:
|
|
1312
1313
|
--version, -v Version string (auto-generated if not provided)
|
|
1313
|
-
--notes, -n Release notes
|
|
1314
|
+
--notes, -n Release notes (required)
|
|
1314
1315
|
--force, -f Skip validation and confirmation
|
|
1315
1316
|
|
|
1316
1317
|
\b
|
|
1317
1318
|
Examples:
|
|
1318
|
-
dxs source branch publish 100
|
|
1319
|
-
dxs source branch publish 100 --version "1.0.0"
|
|
1320
|
-
dxs source branch publish 100 -v "1.0.0" -n "Initial release"
|
|
1319
|
+
dxs source branch publish 100 -n "Initial release" # Auto-generated version
|
|
1320
|
+
dxs source branch publish 100 --version "1.0.0" -n "Initial release"
|
|
1321
1321
|
dxs source branch publish 100 -v "1.1.0" -n "Bug fixes" --force
|
|
1322
1322
|
"""
|
|
1323
1323
|
client = ApiClient()
|
|
@@ -1342,7 +1342,7 @@ def publish(
|
|
|
1342
1342
|
|
|
1343
1343
|
# Auto-generate version if not provided (matches Wavelength UI behavior)
|
|
1344
1344
|
if not version:
|
|
1345
|
-
version =
|
|
1345
|
+
version = generate_version()
|
|
1346
1346
|
ctx.log(f"Auto-generated version: {version}")
|
|
1347
1347
|
|
|
1348
1348
|
# Warn if not publishing from Main branch
|
|
@@ -1379,15 +1379,22 @@ def publish(
|
|
|
1379
1379
|
|
|
1380
1380
|
ctx.log(f"Publishing branch '{branch_name}' as version {version}...")
|
|
1381
1381
|
|
|
1382
|
-
request_data: dict[str, str] = {"version": version}
|
|
1383
|
-
if notes:
|
|
1384
|
-
request_data["releaseNotes"] = notes
|
|
1382
|
+
request_data: dict[str, str] = {"version": version, "releaseNotes": notes}
|
|
1385
1383
|
|
|
1386
1384
|
result = client.post(
|
|
1387
1385
|
BranchEndpoints.publish(branch_id),
|
|
1388
1386
|
data=request_data,
|
|
1389
1387
|
)
|
|
1390
1388
|
|
|
1389
|
+
published_version = None
|
|
1390
|
+
if isinstance(result, dict):
|
|
1391
|
+
published_version = {
|
|
1392
|
+
"versionName": result.get("versionName", version),
|
|
1393
|
+
"versionCode": result.get("versionCode"),
|
|
1394
|
+
"marketPlaceApplicationVersionId": result.get("id"),
|
|
1395
|
+
"isLatest": result.get("isLatest"),
|
|
1396
|
+
}
|
|
1397
|
+
|
|
1391
1398
|
ctx.output(
|
|
1392
1399
|
single(
|
|
1393
1400
|
item={
|
|
@@ -1396,8 +1403,73 @@ def publish(
|
|
|
1396
1403
|
"branch_name": branch_name,
|
|
1397
1404
|
"version": version,
|
|
1398
1405
|
"release_notes": notes,
|
|
1406
|
+
"published_version": published_version,
|
|
1399
1407
|
"result": result,
|
|
1400
1408
|
},
|
|
1401
1409
|
semantic_key="publish_result",
|
|
1402
1410
|
)
|
|
1403
1411
|
)
|
|
1412
|
+
|
|
1413
|
+
|
|
1414
|
+
@branch.command("commit")
|
|
1415
|
+
@click.argument("branch_id", type=int)
|
|
1416
|
+
@click.option("--title", "-t", required=True, help="Commit title")
|
|
1417
|
+
@click.option("--description", "-d", required=True, help="Commit description (required)")
|
|
1418
|
+
@click.option(
|
|
1419
|
+
"--config",
|
|
1420
|
+
"config_refs",
|
|
1421
|
+
multiple=True,
|
|
1422
|
+
help="Reference name of a changed config to commit (repeatable). "
|
|
1423
|
+
"Omit with --all-changes to commit everything modified.",
|
|
1424
|
+
)
|
|
1425
|
+
@click.option(
|
|
1426
|
+
"--all-changes",
|
|
1427
|
+
is_flag=True,
|
|
1428
|
+
default=False,
|
|
1429
|
+
help="Commit all modified configs on the branch.",
|
|
1430
|
+
)
|
|
1431
|
+
@pass_context
|
|
1432
|
+
@require_auth
|
|
1433
|
+
@restrict_in_restricted_mode("commits changes to the Main branch")
|
|
1434
|
+
def commit(
|
|
1435
|
+
ctx: DxsContext,
|
|
1436
|
+
branch_id: int,
|
|
1437
|
+
title: str,
|
|
1438
|
+
description: str,
|
|
1439
|
+
config_refs: tuple[str, ...],
|
|
1440
|
+
all_changes: bool,
|
|
1441
|
+
) -> None:
|
|
1442
|
+
"""Commit (merge) a feature branch into its Main branch.
|
|
1443
|
+
|
|
1444
|
+
\b
|
|
1445
|
+
Examples:
|
|
1446
|
+
dxs source branch commit 3101 --title "bump Module1" -d "Re-pin Module1" --config appConfig
|
|
1447
|
+
"""
|
|
1448
|
+
if not config_refs and not all_changes:
|
|
1449
|
+
raise ValidationError(
|
|
1450
|
+
message="Specify --config <ref> (repeatable) or --all-changes.",
|
|
1451
|
+
suggestions=[
|
|
1452
|
+
"dxs source branch commit 3101 -t 'msg' --config appConfig",
|
|
1453
|
+
"dxs source branch commit 3101 -t 'msg' --all-changes",
|
|
1454
|
+
],
|
|
1455
|
+
)
|
|
1456
|
+
|
|
1457
|
+
client = ApiClient()
|
|
1458
|
+
request_data: dict[str, Any] = {"title": title, "description": description}
|
|
1459
|
+
if not all_changes:
|
|
1460
|
+
request_data["configs"] = list(config_refs)
|
|
1461
|
+
|
|
1462
|
+
ctx.log(f"Committing branch {branch_id}...")
|
|
1463
|
+
result = client.post(SourceControlEndpoints.commit(branch_id), data=request_data)
|
|
1464
|
+
|
|
1465
|
+
ctx.output(
|
|
1466
|
+
single(
|
|
1467
|
+
item={
|
|
1468
|
+
"branch_id": branch_id,
|
|
1469
|
+
"title": title,
|
|
1470
|
+
"new_branch_id": (result or {}).get("newBranchId"),
|
|
1471
|
+
"result": result,
|
|
1472
|
+
},
|
|
1473
|
+
semantic_key="commit_result",
|
|
1474
|
+
)
|
|
1475
|
+
)
|