@get-dx/cli 0.5.1 → 0.5.3
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.
- package/README.md +2 -44
- package/dist/commands/catalog/entities.js +59 -13
- package/dist/commands/studio/reports.js +6 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -18,13 +18,6 @@ Interactively login and install the AI agent skill:
|
|
|
18
18
|
dx init
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
For CI, Docker/dev containers, or other headless environments, pass the token
|
|
22
|
-
through the environment instead of storing it in the OS credential store:
|
|
23
|
-
|
|
24
|
-
```shell
|
|
25
|
-
DX_API_TOKEN="$DX_TOKEN" dx auth status
|
|
26
|
-
```
|
|
27
|
-
|
|
28
21
|
Show help text:
|
|
29
22
|
|
|
30
23
|
```shell
|
|
@@ -32,44 +25,9 @@ dx --help
|
|
|
32
25
|
dx <subcommand> --help
|
|
33
26
|
```
|
|
34
27
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
The CLI requires two base URLs to be configured. The default values are used for DX **cloud** deployments. Users of **dedicated** and **managed** deployments will need to specify these values explicitly when logging in.
|
|
38
|
-
|
|
39
|
-
| Value | How it is used | Env var | Default value |
|
|
40
|
-
| ---------------- | -------------------------------------------- | ----------------- | ----------------------- |
|
|
41
|
-
| **Web base URL** | Browser-based login and displaying web links | `DX_WEB_BASE_URL` | `https://app.getdx.com` |
|
|
42
|
-
| **API base URL** | Making each API request to DX | `DX_API_BASE_URL` | `https://api.getdx.com` |
|
|
43
|
-
|
|
44
|
-
#### For dedicated deployments
|
|
45
|
-
|
|
46
|
-
Set the env vars once when initializing:
|
|
47
|
-
|
|
48
|
-
```shell
|
|
49
|
-
# Interactive login
|
|
50
|
-
DX_WEB_BASE_URL="https://mycompany.getdx.io" DX_API_BASE_URL="https://api.mycompany.getdx.io" dx init
|
|
51
|
-
|
|
52
|
-
# Non-interactive use for CI, containers, or remote agents
|
|
53
|
-
DX_WEB_BASE_URL="https://mycompany.getdx.io" DX_API_BASE_URL="https://api.mycompany.getdx.io" DX_API_TOKEN="$DX_TOKEN" dx auth status
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
#### For managed deployments
|
|
57
|
-
|
|
58
|
-
Set the env vars once when initializing:
|
|
59
|
-
|
|
60
|
-
```shell
|
|
61
|
-
# Interactive login
|
|
62
|
-
DX_WEB_BASE_URL="https://dx.some-example-subdomain.example.com" DX_API_BASE_URL="https://api.dx.some-example-subdomain.example.com" dx init
|
|
63
|
-
|
|
64
|
-
# Non-interactive use for CI, containers, or remote agents
|
|
65
|
-
DX_WEB_BASE_URL="https://dx.some-example-subdomain.example.com" DX_API_BASE_URL="https://api.dx.some-example-subdomain.example.com" DX_API_TOKEN="$DX_TOKEN" dx auth status
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
## Logging
|
|
69
|
-
|
|
70
|
-
Set `DX_LOG_LEVEL` to one of `debug`, `info`, `warn`, or `error` to enable CLI logs.
|
|
28
|
+
## Documentation
|
|
71
29
|
|
|
72
|
-
|
|
30
|
+
For usage instructions and for more information about configuration, visit the [DX CLI documentation](https://docs.getdx.com/cli/).
|
|
73
31
|
|
|
74
32
|
## Developing the CLI
|
|
75
33
|
|
|
@@ -22,7 +22,7 @@ export function entitiesCommand() {
|
|
|
22
22
|
.option("--owner-user-emails <emails>", "Comma-separated owner user emails")
|
|
23
23
|
.option("--owner-user-ids <ids>", "Comma-separated owner user IDs")
|
|
24
24
|
.option("--property <kv>", "Set a property value as key=value. Repeat for multiple properties.", (val, prev) => [...prev, val], [])
|
|
25
|
-
.option("--alias <kv>", "Set an alias
|
|
25
|
+
.option("--alias <kv>", "Set an alias as <type>=<identifier> (short form) or type=<type>,identifier=<id>[,instance_identifier=<instance_id>] (long form). Repeat for multiple aliases.", (val, prev) => [...prev, val], [])
|
|
26
26
|
.addHelpText("afterAll", createExampleText([
|
|
27
27
|
{
|
|
28
28
|
label: "Create a new service entity",
|
|
@@ -41,9 +41,13 @@ export function entitiesCommand() {
|
|
|
41
41
|
command: 'dx catalog entities create --type service --identifier my-service --property tier=Tier-1 --property "languages=Ruby,TypeScript"',
|
|
42
42
|
},
|
|
43
43
|
{
|
|
44
|
-
label: "Create with
|
|
44
|
+
label: "Create with alias (short form)",
|
|
45
45
|
command: "dx catalog entities create --type service --identifier my-service --alias github_repo=12345",
|
|
46
46
|
},
|
|
47
|
+
{
|
|
48
|
+
label: "Create with alias (long form, includes instance identifier)",
|
|
49
|
+
command: 'dx catalog entities create --type service --identifier my-service --alias "type=github_repo,identifier=12345,instance_identifier=789"',
|
|
50
|
+
},
|
|
47
51
|
]))
|
|
48
52
|
.action(wrapAction(async (options, command) => {
|
|
49
53
|
if (!options.identifier) {
|
|
@@ -104,7 +108,7 @@ export function entitiesCommand() {
|
|
|
104
108
|
.option("--owner-user-emails <emails>", "Comma-separated owner user emails")
|
|
105
109
|
.option("--owner-user-ids <ids>", "Comma-separated owner user IDs")
|
|
106
110
|
.option("--property <kv>", "Set a property value as key=value. Repeat for multiple properties. Use value null to remove a property.", (val, prev) => [...prev, val], [])
|
|
107
|
-
.option("--alias <kv>", "Set an alias
|
|
111
|
+
.option("--alias <kv>", "Set an alias as <type>=<identifier> (short form) or type=<type>,identifier=<id>[,instance_identifier=<instance_id>] (long form). Repeat for multiple aliases. Use value null to remove an alias.", (val, prev) => [...prev, val], [])
|
|
108
112
|
.addHelpText("afterAll", createExampleText([
|
|
109
113
|
{
|
|
110
114
|
label: "Rename an entity",
|
|
@@ -119,9 +123,13 @@ export function entitiesCommand() {
|
|
|
119
123
|
command: 'dx catalog entities update my-service --property tier=Tier-1 --property "languages=Ruby,TypeScript"',
|
|
120
124
|
},
|
|
121
125
|
{
|
|
122
|
-
label: "Update
|
|
126
|
+
label: "Update alias (short form)",
|
|
123
127
|
command: "dx catalog entities update my-service --alias github_repo=12345",
|
|
124
128
|
},
|
|
129
|
+
{
|
|
130
|
+
label: "Update alias (long form, includes instance identifier)",
|
|
131
|
+
command: 'dx catalog entities update my-service --alias "type=github_repo,identifier=12345,instance_identifier=789"',
|
|
132
|
+
},
|
|
125
133
|
]))
|
|
126
134
|
.action(wrapAction(async (identifier, options, command) => {
|
|
127
135
|
const runtime = await buildRuntime(getContext(command));
|
|
@@ -148,7 +156,7 @@ export function entitiesCommand() {
|
|
|
148
156
|
.option("--owner-user-emails <emails>", "Comma-separated owner user emails")
|
|
149
157
|
.option("--owner-user-ids <ids>", "Comma-separated owner user IDs")
|
|
150
158
|
.option("--property <kv>", "Set a property value as key=value. Repeat for multiple properties. Use value null to remove a property.", (val, prev) => [...prev, val], [])
|
|
151
|
-
.option("--alias <kv>", "Set an alias
|
|
159
|
+
.option("--alias <kv>", "Set an alias as <type>=<identifier> (short form) or type=<type>,identifier=<id>[,instance_identifier=<instance_id>] (long form). Repeat for multiple aliases. Use value null to remove an alias.", (val, prev) => [...prev, val], [])
|
|
152
160
|
.addHelpText("afterAll", createExampleText([
|
|
153
161
|
{
|
|
154
162
|
label: "Create a new service entity if it does not exist",
|
|
@@ -163,9 +171,13 @@ export function entitiesCommand() {
|
|
|
163
171
|
command: 'dx catalog entities upsert --type service --identifier my-service --property tier=Tier-1 --property "languages=Ruby,TypeScript"',
|
|
164
172
|
},
|
|
165
173
|
{
|
|
166
|
-
label: "Set
|
|
174
|
+
label: "Set alias (short form) while preserving omitted fields",
|
|
167
175
|
command: "dx catalog entities upsert --type service --identifier my-service --alias github_repo=12345",
|
|
168
176
|
},
|
|
177
|
+
{
|
|
178
|
+
label: "Set alias (long form, includes instance identifier)",
|
|
179
|
+
command: 'dx catalog entities upsert --type service --identifier my-service --alias "type=github_repo,identifier=12345,instance_identifier=789"',
|
|
180
|
+
},
|
|
169
181
|
]))
|
|
170
182
|
.action(wrapAction(async (options, command) => {
|
|
171
183
|
if (!options.type) {
|
|
@@ -493,17 +505,47 @@ export function parsePropertyValue(prop, rawValue) {
|
|
|
493
505
|
return rawValue;
|
|
494
506
|
}
|
|
495
507
|
}
|
|
508
|
+
function parseAliasInput(kv) {
|
|
509
|
+
// Long form: type=<alias_type>,identifier=<lookup>[,instance_identifier=<instance_id>]
|
|
510
|
+
if (kv.includes(",")) {
|
|
511
|
+
const pairs = {};
|
|
512
|
+
let validPairs = true;
|
|
513
|
+
for (const pair of kv.split(",")) {
|
|
514
|
+
const eqIdx = pair.indexOf("=");
|
|
515
|
+
if (eqIdx === -1) {
|
|
516
|
+
validPairs = false;
|
|
517
|
+
break;
|
|
518
|
+
}
|
|
519
|
+
pairs[pair.slice(0, eqIdx)] = pair.slice(eqIdx + 1);
|
|
520
|
+
}
|
|
521
|
+
if (validPairs &&
|
|
522
|
+
pairs.type !== undefined &&
|
|
523
|
+
pairs.identifier !== undefined) {
|
|
524
|
+
return {
|
|
525
|
+
key: pairs.type,
|
|
526
|
+
lookup: pairs.identifier,
|
|
527
|
+
...(pairs.instance_identifier !== undefined
|
|
528
|
+
? { instance_identifier: pairs.instance_identifier }
|
|
529
|
+
: {}),
|
|
530
|
+
};
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
// Short form: <alias_type>=<lookup>
|
|
534
|
+
const eqIndex = kv.indexOf("=");
|
|
535
|
+
if (eqIndex === -1)
|
|
536
|
+
return null;
|
|
537
|
+
return { key: kv.slice(0, eqIndex), lookup: kv.slice(eqIndex + 1) };
|
|
538
|
+
}
|
|
496
539
|
function parseEntityAliases(entityTypeIdentifier, rawAliases, knownAliases) {
|
|
497
540
|
const aliasKeys = Object.keys(knownAliases);
|
|
498
541
|
const aliasSet = new Set(aliasKeys);
|
|
499
542
|
const result = {};
|
|
500
543
|
for (const kv of rawAliases) {
|
|
501
|
-
const
|
|
502
|
-
if (
|
|
503
|
-
throw new CliError(`Invalid --alias "${kv}": expected format key=value`, EXIT_CODES.ARGUMENT_ERROR);
|
|
544
|
+
const parsed = parseAliasInput(kv);
|
|
545
|
+
if (!parsed) {
|
|
546
|
+
throw new CliError(`Invalid --alias "${kv}": expected format key=value or type=<type>,identifier=<id>[,instance_identifier=<instance_id>]`, EXIT_CODES.ARGUMENT_ERROR);
|
|
504
547
|
}
|
|
505
|
-
const key =
|
|
506
|
-
const rawValue = kv.slice(eqIndex + 1);
|
|
548
|
+
const { key, lookup, instance_identifier } = parsed;
|
|
507
549
|
if (!aliasSet.has(key)) {
|
|
508
550
|
const availableAliases = aliasKeys
|
|
509
551
|
.sort()
|
|
@@ -512,11 +554,15 @@ function parseEntityAliases(entityTypeIdentifier, rawAliases, knownAliases) {
|
|
|
512
554
|
const availableAliasesText = availableAliases.length > 0 ? availableAliases : "(none)";
|
|
513
555
|
throw new CliError(`Unknown alias \`${key}\` for entity type \`${entityTypeIdentifier}\`. Available aliases: ${availableAliasesText}`, EXIT_CODES.ARGUMENT_ERROR);
|
|
514
556
|
}
|
|
515
|
-
if (
|
|
557
|
+
if (lookup === "null") {
|
|
516
558
|
result[key] = [];
|
|
517
559
|
continue;
|
|
518
560
|
}
|
|
519
|
-
|
|
561
|
+
const aliasEntry = { lookup };
|
|
562
|
+
if (instance_identifier !== undefined) {
|
|
563
|
+
aliasEntry.instance_identifier = instance_identifier;
|
|
564
|
+
}
|
|
565
|
+
result[key] = [...(result[key] ?? []), aliasEntry];
|
|
520
566
|
}
|
|
521
567
|
return result;
|
|
522
568
|
}
|
|
@@ -275,6 +275,7 @@ function renderStudioReport(report) {
|
|
|
275
275
|
ui.dl([
|
|
276
276
|
ui.dli("URL", ui.link(report.url)),
|
|
277
277
|
ui.dli("Description", formatOptionalText(report.description)),
|
|
278
|
+
ui.dli("Owner", formatOwner(report.owner)),
|
|
278
279
|
ui.dli("View access", formatViewAccessType(report.view_access_type)),
|
|
279
280
|
ui.dli("Edit access", formatEditAccessType(report.edit_access_type)),
|
|
280
281
|
ui.dli("Tiles", report.tiles.length.toString()),
|
|
@@ -373,6 +374,11 @@ function formatTileTitle(tile) {
|
|
|
373
374
|
function formatOptionalText(value) {
|
|
374
375
|
return value && value.trim().length > 0 ? value : ui.dim("(None)");
|
|
375
376
|
}
|
|
377
|
+
function formatOwner(owner) {
|
|
378
|
+
if (!owner)
|
|
379
|
+
return ui.dim("(None)");
|
|
380
|
+
return `${owner.name} (${owner.email})`;
|
|
381
|
+
}
|
|
376
382
|
function formatViewAccessType(value) {
|
|
377
383
|
switch (value) {
|
|
378
384
|
case "owner_and_direct_url_only":
|