@get-dx/cli 0.3.4 → 0.3.6
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/assets/logo-d.txt +21 -0
- package/assets/logo-x.txt +21 -0
- package/assets/logo.txt +21 -0
- package/dist/commands/auth.js +3 -3
- package/dist/commands/catalog/entities.js +8 -8
- package/dist/commands/catalog/entityTypes.js +6 -6
- package/dist/commands/init.js +3 -3
- package/dist/commands/scorecards.js +6 -6
- package/dist/commands/snapshots.js +4 -4
- package/dist/commands/studio/query.js +1 -1
- package/dist/commands/teams.js +3 -3
- package/dist/commands/workflowRuns/addLink.js +1 -1
- package/dist/commands/workflowRuns/changeStatus.js +1 -1
- package/dist/commands/workflowRuns/info.js +1 -1
- package/dist/commands/workflowRuns/postMessage.js +1 -1
- package/dist/commands/workflowRuns/trigger.js +1 -1
- package/dist/commands/workflows.js +1 -1
- package/dist/runtime.js +4 -4
- package/dist/secrets.js +62 -20
- package/package.json +3 -1
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
████████████████
|
|
6
|
+
█████████████████
|
|
7
|
+
████████████████
|
|
8
|
+
██████ ████████
|
|
9
|
+
██████ ███████
|
|
10
|
+
██████ ███████
|
|
11
|
+
██████ ███████
|
|
12
|
+
██████ ███████
|
|
13
|
+
██████ ███████
|
|
14
|
+
██████ ███████
|
|
15
|
+
██████ ████████
|
|
16
|
+
██████████████████████
|
|
17
|
+
████████████████████
|
|
18
|
+
█████████████████
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
package/assets/logo.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
████████████████ ███████ ████████
|
|
6
|
+
█████████████████ ███████ ███████
|
|
7
|
+
████████████████ ███████ ███████
|
|
8
|
+
██████ ████████ ████ ████████
|
|
9
|
+
██████ ███████ ██ ███████
|
|
10
|
+
██████ ███████ ███████
|
|
11
|
+
██████ ███████ ████████
|
|
12
|
+
██████ ███████ ███████
|
|
13
|
+
██████ ███████ ███████
|
|
14
|
+
██████ ███████ ████████ █
|
|
15
|
+
██████ ████████ ████████ █████
|
|
16
|
+
██████████████████████ ███████ ██████
|
|
17
|
+
████████████████████ ████████ ███████
|
|
18
|
+
█████████████████ ████████ ████████
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
package/dist/commands/auth.js
CHANGED
|
@@ -59,14 +59,14 @@ export function authCommand() {
|
|
|
59
59
|
throw new CliError("Account web API token or personal access token is required");
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
|
-
const runtime = buildRuntime(context, {
|
|
62
|
+
const runtime = await buildRuntime(context, {
|
|
63
63
|
apiBaseUrl,
|
|
64
64
|
token,
|
|
65
65
|
webBaseUrl,
|
|
66
66
|
});
|
|
67
67
|
const response = await getAuthInfo(runtime);
|
|
68
68
|
persistBaseUrls(apiBaseUrl, webBaseUrl);
|
|
69
|
-
setToken(apiBaseUrl, token);
|
|
69
|
+
await setToken(apiBaseUrl, token);
|
|
70
70
|
if (context.json) {
|
|
71
71
|
renderJson({
|
|
72
72
|
...response,
|
|
@@ -114,7 +114,7 @@ export function authCommand() {
|
|
|
114
114
|
},
|
|
115
115
|
]))
|
|
116
116
|
.action(wrapAction(async (_options, command) => {
|
|
117
|
-
const runtime = buildRuntime(getContext(command));
|
|
117
|
+
const runtime = await buildRuntime(getContext(command));
|
|
118
118
|
const response = await getAuthInfo(runtime);
|
|
119
119
|
if (runtime.context.json) {
|
|
120
120
|
renderJson({
|
|
@@ -51,7 +51,7 @@ export function entitiesCommand() {
|
|
|
51
51
|
if (!options.type) {
|
|
52
52
|
throw new CliError("--type is required", EXIT_CODES.ARGUMENT_ERROR);
|
|
53
53
|
}
|
|
54
|
-
const runtime = buildRuntime(getContext(command));
|
|
54
|
+
const runtime = await buildRuntime(getContext(command));
|
|
55
55
|
const resolvedValues = await resolveValuesForEntityType(runtime, options.type, options.property, options.alias);
|
|
56
56
|
const response = await createEntity(runtime, options.identifier, {
|
|
57
57
|
type: options.type,
|
|
@@ -87,7 +87,7 @@ export function entitiesCommand() {
|
|
|
87
87
|
},
|
|
88
88
|
]))
|
|
89
89
|
.action(wrapAction(async (identifier, _options, command) => {
|
|
90
|
-
const runtime = buildRuntime(getContext(command));
|
|
90
|
+
const runtime = await buildRuntime(getContext(command));
|
|
91
91
|
const response = await deleteEntity(runtime, identifier);
|
|
92
92
|
if (runtime.context.json) {
|
|
93
93
|
renderJson(response);
|
|
@@ -125,7 +125,7 @@ export function entitiesCommand() {
|
|
|
125
125
|
},
|
|
126
126
|
]))
|
|
127
127
|
.action(wrapAction(async (identifier, options, command) => {
|
|
128
|
-
const runtime = buildRuntime(getContext(command));
|
|
128
|
+
const runtime = await buildRuntime(getContext(command));
|
|
129
129
|
const resolvedValues = await resolveValuesForExistingEntity(runtime, identifier, options.property, options.alias);
|
|
130
130
|
const response = await updateEntity(runtime, identifier, {
|
|
131
131
|
...getEntityMutationOptionValues(options),
|
|
@@ -174,7 +174,7 @@ export function entitiesCommand() {
|
|
|
174
174
|
if (!options.identifier) {
|
|
175
175
|
throw new CliError("--identifier is required", EXIT_CODES.ARGUMENT_ERROR);
|
|
176
176
|
}
|
|
177
|
-
const runtime = buildRuntime(getContext(command));
|
|
177
|
+
const runtime = await buildRuntime(getContext(command));
|
|
178
178
|
const resolvedValues = await resolveValuesForEntityType(runtime, options.type, options.property, options.alias);
|
|
179
179
|
const response = await upsertEntity(runtime, options.identifier, {
|
|
180
180
|
type: options.type,
|
|
@@ -210,7 +210,7 @@ export function entitiesCommand() {
|
|
|
210
210
|
},
|
|
211
211
|
]))
|
|
212
212
|
.action(wrapAction(async (identifier, options, command) => {
|
|
213
|
-
const runtime = buildRuntime(getContext(command));
|
|
213
|
+
const runtime = await buildRuntime(getContext(command));
|
|
214
214
|
const response = await getEntity(runtime, identifier);
|
|
215
215
|
const processedResponse = processIncludes(response, options);
|
|
216
216
|
if (runtime.context.json) {
|
|
@@ -247,7 +247,7 @@ export function entitiesCommand() {
|
|
|
247
247
|
},
|
|
248
248
|
]))
|
|
249
249
|
.action(wrapAction(async (options, command) => {
|
|
250
|
-
const runtime = buildRuntime(getContext(command));
|
|
250
|
+
const runtime = await buildRuntime(getContext(command));
|
|
251
251
|
const response = await listEntities(runtime, {
|
|
252
252
|
cursor: options.cursor,
|
|
253
253
|
limit: options.limit,
|
|
@@ -284,7 +284,7 @@ export function entitiesCommand() {
|
|
|
284
284
|
},
|
|
285
285
|
]))
|
|
286
286
|
.action(wrapAction(async (identifier, options, command) => {
|
|
287
|
-
const runtime = buildRuntime(getContext(command));
|
|
287
|
+
const runtime = await buildRuntime(getContext(command));
|
|
288
288
|
const response = await getEntityTasks(runtime, identifier, {
|
|
289
289
|
cursor: options.cursor,
|
|
290
290
|
limit: options.limit,
|
|
@@ -317,7 +317,7 @@ export function entitiesCommand() {
|
|
|
317
317
|
},
|
|
318
318
|
]))
|
|
319
319
|
.action(wrapAction(async (identifier, options, command) => {
|
|
320
|
-
const runtime = buildRuntime(getContext(command));
|
|
320
|
+
const runtime = await buildRuntime(getContext(command));
|
|
321
321
|
const response = await getEntityScorecards(runtime, identifier, {
|
|
322
322
|
cursor: options.cursor,
|
|
323
323
|
limit: options.limit,
|
|
@@ -39,7 +39,7 @@ export function entityTypesCommand() {
|
|
|
39
39
|
if (modeCount > 1) {
|
|
40
40
|
throw new CliError("--from-file and --from-stdin are mutually exclusive", EXIT_CODES.ARGUMENT_ERROR);
|
|
41
41
|
}
|
|
42
|
-
const runtime = buildRuntime(getContext(command));
|
|
42
|
+
const runtime = await buildRuntime(getContext(command));
|
|
43
43
|
let raw;
|
|
44
44
|
if (options.fromFile) {
|
|
45
45
|
raw = readYamlFile(options.fromFile);
|
|
@@ -71,7 +71,7 @@ export function entityTypesCommand() {
|
|
|
71
71
|
},
|
|
72
72
|
]))
|
|
73
73
|
.action(wrapAction(async (identifier, _options, command) => {
|
|
74
|
-
const runtime = buildRuntime(getContext(command));
|
|
74
|
+
const runtime = await buildRuntime(getContext(command));
|
|
75
75
|
const response = await deleteEntityType(runtime, identifier);
|
|
76
76
|
if (runtime.context.json) {
|
|
77
77
|
renderJson(response);
|
|
@@ -99,7 +99,7 @@ export function entityTypesCommand() {
|
|
|
99
99
|
},
|
|
100
100
|
]))
|
|
101
101
|
.action(wrapAction(async (identifier, options, command) => {
|
|
102
|
-
const runtime = buildRuntime(getContext(command));
|
|
102
|
+
const runtime = await buildRuntime(getContext(command));
|
|
103
103
|
const response = await getEntityType(runtime, identifier);
|
|
104
104
|
const processedEntityType = processEntityTypeIncludes(response.entity_type, options);
|
|
105
105
|
if (runtime.context.json) {
|
|
@@ -125,7 +125,7 @@ export function entityTypesCommand() {
|
|
|
125
125
|
},
|
|
126
126
|
]))
|
|
127
127
|
.action(wrapAction(async (path, options, command) => {
|
|
128
|
-
const runtime = buildRuntime(getContext(command));
|
|
128
|
+
const runtime = await buildRuntime(getContext(command));
|
|
129
129
|
if (options.identifier) {
|
|
130
130
|
const identifier = options.identifier;
|
|
131
131
|
let entityTypeResponse;
|
|
@@ -190,7 +190,7 @@ export function entityTypesCommand() {
|
|
|
190
190
|
},
|
|
191
191
|
]))
|
|
192
192
|
.action(wrapAction(async (options, command) => {
|
|
193
|
-
const runtime = buildRuntime(getContext(command));
|
|
193
|
+
const runtime = await buildRuntime(getContext(command));
|
|
194
194
|
const response = await listEntityTypes(runtime, {
|
|
195
195
|
cursor: options.cursor,
|
|
196
196
|
limit: options.limit,
|
|
@@ -231,7 +231,7 @@ export function entityTypesCommand() {
|
|
|
231
231
|
if (modeCount > 1) {
|
|
232
232
|
throw new CliError("--from-file and --from-stdin are mutually exclusive", EXIT_CODES.ARGUMENT_ERROR);
|
|
233
233
|
}
|
|
234
|
-
const runtime = buildRuntime(getContext(command));
|
|
234
|
+
const runtime = await buildRuntime(getContext(command));
|
|
235
235
|
let raw;
|
|
236
236
|
if (options.fromFile) {
|
|
237
237
|
raw = readYamlFile(options.fromFile);
|
package/dist/commands/init.js
CHANGED
|
@@ -31,7 +31,7 @@ export function initCommand() {
|
|
|
31
31
|
]))
|
|
32
32
|
.action(wrapAction(async (commandOptions, command) => {
|
|
33
33
|
const context = getContext(command);
|
|
34
|
-
let runtime = buildRuntimeSafe(context);
|
|
34
|
+
let runtime = await buildRuntimeSafe(context);
|
|
35
35
|
ensureInteractive();
|
|
36
36
|
await renderWelcomeAnimation();
|
|
37
37
|
runtime = await ensureLoggedIn(context, runtime);
|
|
@@ -92,7 +92,7 @@ async function attemptLogin(apiBaseUrl, webBaseUrl, context) {
|
|
|
92
92
|
if (!token) {
|
|
93
93
|
throw new CliError("Account web API token is required");
|
|
94
94
|
}
|
|
95
|
-
const runtime = buildRuntime(context, {
|
|
95
|
+
const runtime = await buildRuntime(context, {
|
|
96
96
|
apiBaseUrl,
|
|
97
97
|
token,
|
|
98
98
|
webBaseUrl,
|
|
@@ -103,7 +103,7 @@ async function attemptLogin(apiBaseUrl, webBaseUrl, context) {
|
|
|
103
103
|
throw new CliError(`Login failed`);
|
|
104
104
|
}
|
|
105
105
|
persistBaseUrls(apiBaseUrl, webBaseUrl);
|
|
106
|
-
setToken(apiBaseUrl, token);
|
|
106
|
+
await setToken(apiBaseUrl, token);
|
|
107
107
|
renderAuthInfo(response, token, apiBaseUrl);
|
|
108
108
|
return runtime;
|
|
109
109
|
}
|
|
@@ -39,7 +39,7 @@ export function scorecardsCommand() {
|
|
|
39
39
|
if (modeCount > 1) {
|
|
40
40
|
throw new CliError("--from-file and --from-stdin are mutually exclusive", EXIT_CODES.ARGUMENT_ERROR);
|
|
41
41
|
}
|
|
42
|
-
const runtime = buildRuntime(getContext(command));
|
|
42
|
+
const runtime = await buildRuntime(getContext(command));
|
|
43
43
|
let raw;
|
|
44
44
|
if (options.fromFile) {
|
|
45
45
|
raw = readYamlFile(options.fromFile);
|
|
@@ -71,7 +71,7 @@ export function scorecardsCommand() {
|
|
|
71
71
|
},
|
|
72
72
|
]))
|
|
73
73
|
.action(wrapAction(async (id, _options, command) => {
|
|
74
|
-
const runtime = buildRuntime(getContext(command));
|
|
74
|
+
const runtime = await buildRuntime(getContext(command));
|
|
75
75
|
await deleteScorecard(runtime, id);
|
|
76
76
|
if (runtime.context.json) {
|
|
77
77
|
renderJson({ ok: true });
|
|
@@ -103,7 +103,7 @@ export function scorecardsCommand() {
|
|
|
103
103
|
]))
|
|
104
104
|
.action(wrapAction(async (id, options, command) => {
|
|
105
105
|
const includeSections = parseScorecardIncludeSections(options.include);
|
|
106
|
-
const runtime = buildRuntime(getContext(command));
|
|
106
|
+
const runtime = await buildRuntime(getContext(command));
|
|
107
107
|
const response = await getScorecard(runtime, id);
|
|
108
108
|
if (runtime.context.json) {
|
|
109
109
|
const processedScorecard = processScorecardIncludes(response.scorecard, includeSections);
|
|
@@ -129,7 +129,7 @@ export function scorecardsCommand() {
|
|
|
129
129
|
},
|
|
130
130
|
]))
|
|
131
131
|
.action(wrapAction(async (path, options, command) => {
|
|
132
|
-
const runtime = buildRuntime(getContext(command));
|
|
132
|
+
const runtime = await buildRuntime(getContext(command));
|
|
133
133
|
if (options.id) {
|
|
134
134
|
const id = options.id;
|
|
135
135
|
let scorecardResponse;
|
|
@@ -200,7 +200,7 @@ export function scorecardsCommand() {
|
|
|
200
200
|
]))
|
|
201
201
|
.action(wrapAction(async (options, command) => {
|
|
202
202
|
const includeSections = parseScorecardIncludeSections(options.include);
|
|
203
|
-
const runtime = buildRuntime(getContext(command));
|
|
203
|
+
const runtime = await buildRuntime(getContext(command));
|
|
204
204
|
const response = await listScorecards(runtime, {
|
|
205
205
|
cursor: options.cursor,
|
|
206
206
|
limit: options.limit,
|
|
@@ -242,7 +242,7 @@ export function scorecardsCommand() {
|
|
|
242
242
|
if (modeCount > 1) {
|
|
243
243
|
throw new CliError("--from-file and --from-stdin are mutually exclusive", EXIT_CODES.ARGUMENT_ERROR);
|
|
244
244
|
}
|
|
245
|
-
const runtime = buildRuntime(getContext(command));
|
|
245
|
+
const runtime = await buildRuntime(getContext(command));
|
|
246
246
|
let raw;
|
|
247
247
|
if (options.fromFile) {
|
|
248
248
|
raw = readYamlFile(options.fromFile);
|
|
@@ -34,7 +34,7 @@ export function snapshotsCommand() {
|
|
|
34
34
|
]))
|
|
35
35
|
.action(wrapAction(async (options, command) => {
|
|
36
36
|
const id = parseRequiredTextOption(options.id, "--id");
|
|
37
|
-
const runtime = buildRuntime(getContext(command));
|
|
37
|
+
const runtime = await buildRuntime(getContext(command));
|
|
38
38
|
const response = await listSnapshotCsatComments(runtime, {
|
|
39
39
|
id,
|
|
40
40
|
cursor: options.cursor,
|
|
@@ -73,7 +73,7 @@ export function snapshotsCommand() {
|
|
|
73
73
|
]))
|
|
74
74
|
.action(wrapAction(async (options, command) => {
|
|
75
75
|
const id = parseRequiredTextOption(options.id, "--id");
|
|
76
|
-
const runtime = buildRuntime(getContext(command));
|
|
76
|
+
const runtime = await buildRuntime(getContext(command));
|
|
77
77
|
const response = await listSnapshotDriverComments(runtime, {
|
|
78
78
|
id,
|
|
79
79
|
cursor: options.cursor,
|
|
@@ -103,7 +103,7 @@ export function snapshotsCommand() {
|
|
|
103
103
|
]))
|
|
104
104
|
.action(wrapAction(async (options, command) => {
|
|
105
105
|
const snapshotId = parseRequiredTextOption(options.id, "--id");
|
|
106
|
-
const runtime = buildRuntime(getContext(command));
|
|
106
|
+
const runtime = await buildRuntime(getContext(command));
|
|
107
107
|
const response = await getSnapshotInfo(runtime, snapshotId);
|
|
108
108
|
if (runtime.context.json) {
|
|
109
109
|
renderJson(response);
|
|
@@ -126,7 +126,7 @@ export function snapshotsCommand() {
|
|
|
126
126
|
},
|
|
127
127
|
]))
|
|
128
128
|
.action(wrapAction(async (_options, command) => {
|
|
129
|
-
const runtime = buildRuntime(getContext(command));
|
|
129
|
+
const runtime = await buildRuntime(getContext(command));
|
|
130
130
|
const response = await listSnapshots(runtime);
|
|
131
131
|
if (runtime.context.json) {
|
|
132
132
|
renderJson(response);
|
|
@@ -50,7 +50,7 @@ export function queryCommand() {
|
|
|
50
50
|
throw new CliError("--output cannot be used with --json", EXIT_CODES.ARGUMENT_ERROR);
|
|
51
51
|
}
|
|
52
52
|
const variables = parseVariables(options.variable);
|
|
53
|
-
const runtime = buildRuntime(context);
|
|
53
|
+
const runtime = await buildRuntime(context);
|
|
54
54
|
const progress = new AsyncProgressReporter();
|
|
55
55
|
const queryRun = await executeQuery(runtime, progress, sql, variables);
|
|
56
56
|
await waitForQuery(runtime, progress, queryRun.id);
|
package/dist/commands/teams.js
CHANGED
|
@@ -23,7 +23,7 @@ export function teamsCommand() {
|
|
|
23
23
|
]))
|
|
24
24
|
.action(wrapAction(async (options, command) => {
|
|
25
25
|
const teamEmails = parseTeamEmails(options.teamEmails);
|
|
26
|
-
const runtime = buildRuntime(getContext(command));
|
|
26
|
+
const runtime = await buildRuntime(getContext(command));
|
|
27
27
|
const response = await findTeamByMembers(runtime, teamEmails);
|
|
28
28
|
if (runtime.context.json) {
|
|
29
29
|
renderJson(response);
|
|
@@ -53,7 +53,7 @@ export function teamsCommand() {
|
|
|
53
53
|
]))
|
|
54
54
|
.action(wrapAction(async (options, command) => {
|
|
55
55
|
const lookup = parseTeamInfoLookup(options);
|
|
56
|
-
const runtime = buildRuntime(getContext(command));
|
|
56
|
+
const runtime = await buildRuntime(getContext(command));
|
|
57
57
|
const response = await getTeamInfo(runtime, lookup);
|
|
58
58
|
if (runtime.context.json) {
|
|
59
59
|
renderJson(response);
|
|
@@ -76,7 +76,7 @@ export function teamsCommand() {
|
|
|
76
76
|
},
|
|
77
77
|
]))
|
|
78
78
|
.action(wrapAction(async (_options, command) => {
|
|
79
|
-
const runtime = buildRuntime(getContext(command));
|
|
79
|
+
const runtime = await buildRuntime(getContext(command));
|
|
80
80
|
const response = await listTeams(runtime);
|
|
81
81
|
if (runtime.context.json) {
|
|
82
82
|
renderJson(response);
|
|
@@ -19,7 +19,7 @@ export function addLinkCommand() {
|
|
|
19
19
|
]))
|
|
20
20
|
.action(wrapAction(async (workflowRunId, options, command) => {
|
|
21
21
|
const context = getContext(command);
|
|
22
|
-
const runtime = buildRuntime(context);
|
|
22
|
+
const runtime = await buildRuntime(context);
|
|
23
23
|
const response = await addLink(runtime, workflowRunId, options.url, options.label);
|
|
24
24
|
if (runtime.context.json) {
|
|
25
25
|
renderJson(response);
|
|
@@ -23,7 +23,7 @@ export function changeStatusCommand() {
|
|
|
23
23
|
]))
|
|
24
24
|
.action(wrapAction(async (workflowRunId, options, command) => {
|
|
25
25
|
const context = getContext(command);
|
|
26
|
-
const runtime = buildRuntime(context);
|
|
26
|
+
const runtime = await buildRuntime(context);
|
|
27
27
|
if (!isValidStatus(options.status)) {
|
|
28
28
|
throw new CliError(`Invalid status: ${options.status}. Must be one of: SUCCEEDED, FAILED.`, EXIT_CODES.ARGUMENT_ERROR);
|
|
29
29
|
}
|
|
@@ -18,7 +18,7 @@ export function infoCommand() {
|
|
|
18
18
|
]))
|
|
19
19
|
.action(wrapAction(async (workflowRunId, options, command) => {
|
|
20
20
|
const context = getContext(command);
|
|
21
|
-
const runtime = buildRuntime(context);
|
|
21
|
+
const runtime = await buildRuntime(context);
|
|
22
22
|
const infoResponse = await getWorkflowRun(runtime, workflowRunId);
|
|
23
23
|
const workflowRun = infoResponse.body.workflow_run;
|
|
24
24
|
if (runtime.context.json) {
|
|
@@ -22,7 +22,7 @@ export function postMessageCommand() {
|
|
|
22
22
|
]))
|
|
23
23
|
.action(wrapAction(async (workflowRunId, options, command) => {
|
|
24
24
|
const context = getContext(command);
|
|
25
|
-
const runtime = buildRuntime(context);
|
|
25
|
+
const runtime = await buildRuntime(context);
|
|
26
26
|
const response = await postMessage(runtime, workflowRunId, options.message);
|
|
27
27
|
if (runtime.context.json) {
|
|
28
28
|
renderJson(response);
|
|
@@ -52,7 +52,7 @@ export function triggerCommand() {
|
|
|
52
52
|
]))
|
|
53
53
|
.action(wrapAction(async (workflowIdentifier, options, command) => {
|
|
54
54
|
const context = getContext(command);
|
|
55
|
-
const runtime = buildRuntime(context);
|
|
55
|
+
const runtime = await buildRuntime(context);
|
|
56
56
|
// Fetch list of all workflows, find the one that applies
|
|
57
57
|
const workflowsResponse = await listWorkflows(runtime, {});
|
|
58
58
|
const workflow = workflowsResponse.workflows.find((w) => w.identifier === workflowIdentifier);
|
|
@@ -35,7 +35,7 @@ export function workflowsCommand() {
|
|
|
35
35
|
if (entityIdentifier && scope !== "ENTITY") {
|
|
36
36
|
throw new CliError("--entity-identifier requires --scope ENTITY", EXIT_CODES.ARGUMENT_ERROR);
|
|
37
37
|
}
|
|
38
|
-
const runtime = buildRuntime(getContext(command));
|
|
38
|
+
const runtime = await buildRuntime(getContext(command));
|
|
39
39
|
const response = await listWorkflows(runtime, {
|
|
40
40
|
scope,
|
|
41
41
|
entity_identifier: entityIdentifier,
|
package/dist/runtime.js
CHANGED
|
@@ -6,10 +6,10 @@ import cliPackage from "../package.json" with { type: "json" };
|
|
|
6
6
|
export function buildLogger(context) {
|
|
7
7
|
return createLogger({ json: context.json || !process.stderr.isTTY });
|
|
8
8
|
}
|
|
9
|
-
export function buildRuntime(context, overrides) {
|
|
9
|
+
export async function buildRuntime(context, overrides) {
|
|
10
10
|
const apiBaseUrl = overrides?.apiBaseUrl ?? resolveApiBaseUrl();
|
|
11
11
|
const webBaseUrl = overrides?.webBaseUrl ?? resolveWebBaseUrl();
|
|
12
|
-
const token = overrides?.token ?? getToken(apiBaseUrl);
|
|
12
|
+
const token = overrides?.token ?? (await getToken(apiBaseUrl));
|
|
13
13
|
if (!token) {
|
|
14
14
|
throw new CliError("No API token configured. Run `dx auth login --token <token>` or set DX_API_TOKEN.");
|
|
15
15
|
}
|
|
@@ -22,10 +22,10 @@ export function buildRuntime(context, overrides) {
|
|
|
22
22
|
logger: buildLogger(context),
|
|
23
23
|
};
|
|
24
24
|
}
|
|
25
|
-
export function buildRuntimeSafe(context, overrides) {
|
|
25
|
+
export async function buildRuntimeSafe(context, overrides) {
|
|
26
26
|
const apiBaseUrl = overrides?.apiBaseUrl ?? resolveApiBaseUrl();
|
|
27
27
|
const webBaseUrl = overrides?.webBaseUrl ?? resolveWebBaseUrl();
|
|
28
|
-
const token = overrides?.token ?? getToken(apiBaseUrl);
|
|
28
|
+
const token = overrides?.token ?? (await getToken(apiBaseUrl));
|
|
29
29
|
if (!token) {
|
|
30
30
|
return null;
|
|
31
31
|
}
|
package/dist/secrets.js
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { execa } from "execa";
|
|
2
|
+
import * as crossKeychain from "cross-keychain";
|
|
2
3
|
import { CliError } from "./errors.js";
|
|
3
4
|
const SERVICE = "dx-cli";
|
|
4
|
-
export function getToken(baseUrl) {
|
|
5
|
+
export async function getToken(baseUrl) {
|
|
5
6
|
if (process.env.DX_API_TOKEN) {
|
|
6
7
|
return process.env.DX_API_TOKEN;
|
|
7
8
|
}
|
|
8
|
-
return getSecretStore().get(baseUrl);
|
|
9
|
+
return await getSecretStore().get(baseUrl);
|
|
9
10
|
}
|
|
10
|
-
export function setToken(baseUrl, token) {
|
|
11
|
-
getSecretStore().set(baseUrl, token);
|
|
11
|
+
export async function setToken(baseUrl, token) {
|
|
12
|
+
await getSecretStore().set(baseUrl, token);
|
|
12
13
|
}
|
|
13
|
-
export function deleteToken(baseUrl) {
|
|
14
|
-
getSecretStore().delete(baseUrl);
|
|
14
|
+
export async function deleteToken(baseUrl) {
|
|
15
|
+
await getSecretStore().delete(baseUrl);
|
|
15
16
|
}
|
|
16
17
|
function getSecretStore(platform = process.platform) {
|
|
17
18
|
if (platform === "darwin") {
|
|
@@ -20,28 +21,32 @@ function getSecretStore(platform = process.platform) {
|
|
|
20
21
|
if (platform === "linux") {
|
|
21
22
|
return linuxSecretStore();
|
|
22
23
|
}
|
|
24
|
+
if (platform === "win32") {
|
|
25
|
+
return windowsSecretStore();
|
|
26
|
+
}
|
|
23
27
|
throw new CliError(`Unsupported platform for secure token storage: ${platform}`);
|
|
24
28
|
}
|
|
25
29
|
function macosSecretStore() {
|
|
26
30
|
return {
|
|
27
|
-
get(baseUrl) {
|
|
31
|
+
async get(baseUrl) {
|
|
28
32
|
try {
|
|
29
|
-
|
|
33
|
+
const result = await execa("security", [
|
|
30
34
|
"find-generic-password",
|
|
31
35
|
"-s",
|
|
32
36
|
SERVICE,
|
|
33
37
|
"-a",
|
|
34
38
|
baseUrl,
|
|
35
39
|
"-w",
|
|
36
|
-
])
|
|
40
|
+
]);
|
|
41
|
+
return result.stdout?.trim() ?? null;
|
|
37
42
|
}
|
|
38
43
|
catch {
|
|
39
44
|
return null;
|
|
40
45
|
}
|
|
41
46
|
},
|
|
42
|
-
set(baseUrl, token) {
|
|
47
|
+
async set(baseUrl, token) {
|
|
43
48
|
try {
|
|
44
|
-
|
|
49
|
+
await execa("security", [
|
|
45
50
|
"add-generic-password",
|
|
46
51
|
"-U",
|
|
47
52
|
"-s",
|
|
@@ -63,9 +68,9 @@ function macosSecretStore() {
|
|
|
63
68
|
.join("\n"));
|
|
64
69
|
}
|
|
65
70
|
},
|
|
66
|
-
delete(baseUrl) {
|
|
71
|
+
async delete(baseUrl) {
|
|
67
72
|
try {
|
|
68
|
-
|
|
73
|
+
await execa("security", [
|
|
69
74
|
"delete-generic-password",
|
|
70
75
|
"-s",
|
|
71
76
|
SERVICE,
|
|
@@ -81,33 +86,70 @@ function macosSecretStore() {
|
|
|
81
86
|
}
|
|
82
87
|
function linuxSecretStore() {
|
|
83
88
|
return {
|
|
84
|
-
get(baseUrl) {
|
|
89
|
+
async get(baseUrl) {
|
|
85
90
|
try {
|
|
86
|
-
|
|
91
|
+
const result = await execa("secret-tool", [
|
|
87
92
|
"lookup",
|
|
88
93
|
"service",
|
|
89
94
|
SERVICE,
|
|
90
95
|
"account",
|
|
91
96
|
baseUrl,
|
|
92
|
-
])
|
|
97
|
+
]);
|
|
98
|
+
return result.stdout?.trim() ?? null;
|
|
93
99
|
}
|
|
94
100
|
catch {
|
|
95
101
|
return null;
|
|
96
102
|
}
|
|
97
103
|
},
|
|
98
|
-
set(baseUrl, token) {
|
|
104
|
+
async set(baseUrl, token) {
|
|
99
105
|
try {
|
|
100
|
-
|
|
106
|
+
await execa("secret-tool", ["store", "--label=dx-cli", "service", SERVICE, "account", baseUrl], { input: token });
|
|
101
107
|
}
|
|
102
108
|
catch (error) {
|
|
103
109
|
throw buildLinuxTokenStorageError(error);
|
|
104
110
|
}
|
|
105
111
|
},
|
|
106
|
-
delete(_baseUrl) {
|
|
112
|
+
async delete(_baseUrl) {
|
|
107
113
|
throw new CliError("Linux token deletion is not supported by secret-tool in this implementation");
|
|
108
114
|
},
|
|
109
115
|
};
|
|
110
116
|
}
|
|
117
|
+
function windowsSecretStore() {
|
|
118
|
+
return {
|
|
119
|
+
async get(baseUrl) {
|
|
120
|
+
try {
|
|
121
|
+
return await crossKeychain.getPassword(SERVICE, encodeAccountName(baseUrl));
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
async set(baseUrl, token) {
|
|
128
|
+
try {
|
|
129
|
+
await crossKeychain.setPassword(SERVICE, encodeAccountName(baseUrl), token);
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
throw new CliError([
|
|
133
|
+
"Unable to save the DX API token securely using Windows Credential Manager.",
|
|
134
|
+
"",
|
|
135
|
+
"Set DX_API_TOKEN in the environment, or try again from a Windows session with Credential Manager access.",
|
|
136
|
+
formatErrorDetails(error),
|
|
137
|
+
]
|
|
138
|
+
.filter(Boolean)
|
|
139
|
+
.join("\n"));
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
async delete(baseUrl) {
|
|
143
|
+
await crossKeychain.deletePassword(SERVICE, encodeAccountName(baseUrl));
|
|
144
|
+
},
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Encode an account name so it has only valid characters for Windows.
|
|
149
|
+
*/
|
|
150
|
+
function encodeAccountName(baseUrl) {
|
|
151
|
+
return Buffer.from(baseUrl).toString("base64");
|
|
152
|
+
}
|
|
111
153
|
function buildLinuxTokenStorageError(error) {
|
|
112
154
|
if (hasErrorCode(error, "ENOENT")) {
|
|
113
155
|
return new CliError([
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@get-dx/cli",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.6",
|
|
4
4
|
"description": "DX CLI",
|
|
5
5
|
"author": "DX <developers@getdx.com>",
|
|
6
6
|
"bugs": {
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"dx": "dist/index.js"
|
|
12
12
|
},
|
|
13
13
|
"files": [
|
|
14
|
+
"assets",
|
|
14
15
|
"dist"
|
|
15
16
|
],
|
|
16
17
|
"homepage": "https://github.com/get-dx/cli#readme",
|
|
@@ -40,6 +41,7 @@
|
|
|
40
41
|
"dependencies": {
|
|
41
42
|
"@inquirer/prompts": "^8.4.1",
|
|
42
43
|
"commander": "^14.0.1",
|
|
44
|
+
"cross-keychain": "^1.1.0",
|
|
43
45
|
"dayjs": "^1.11.20",
|
|
44
46
|
"execa": "^9.6.1",
|
|
45
47
|
"open": "^11.0.0",
|