dataiku-sdk 4.0.0 → 4.2.0
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 +1 -0
- package/dist/build-metadata.json +1 -1
- package/dist/packages/types/src/index.d.ts +5 -1
- package/dist/packages/types/src/index.js +5 -1
- package/dist/src/cli/command-syntax.json +4136 -2756
- package/dist/src/cli/commands/code-env.js +5 -3
- package/dist/src/cli/commands/dataset.js +6 -4
- package/dist/src/cli/commands/future.js +7 -2
- package/dist/src/cli/commands/index.js +4 -0
- package/dist/src/cli/commands/job.js +12 -9
- package/dist/src/cli/commands/messaging-channel.d.ts +17 -0
- package/dist/src/cli/commands/messaging-channel.js +385 -0
- package/dist/src/cli/commands/project-deployer.js +33 -0
- package/dist/src/cli/commands/project.js +30 -0
- package/dist/src/cli/commands/recipe.js +23 -2
- package/dist/src/cli/commands/scenario.d.ts +6 -0
- package/dist/src/cli/commands/scenario.js +495 -17
- package/dist/src/cli/contract.js +20 -4
- package/dist/src/cli/env.d.ts +6 -0
- package/dist/src/cli/env.js +8 -0
- package/dist/src/cli/flags.js +34 -0
- package/dist/src/cli/helpers/cleanup.js +11 -0
- package/dist/src/cli/list-shapes.js +5 -0
- package/dist/src/cli/output.d.ts +2 -0
- package/dist/src/cli/output.js +24 -4
- package/dist/src/cli/plans.js +94 -2
- package/dist/src/cli/read-shapes.js +92 -1
- package/dist/src/cli/result-shapes.d.ts +19 -1
- package/dist/src/cli/result-shapes.js +228 -4
- package/dist/src/cli/selector-suggestions.d.ts +14 -0
- package/dist/src/cli/selector-suggestions.js +56 -0
- package/dist/src/cli/usage.d.ts +1 -1
- package/dist/src/cli/usage.js +36 -4
- package/dist/src/cli/version.d.ts +2 -2
- package/dist/src/cli/version.js +2 -2
- package/dist/src/cli.js +62 -13
- package/dist/src/client.d.ts +16 -4
- package/dist/src/client.js +45 -9
- package/dist/src/errors.d.ts +2 -0
- package/dist/src/errors.js +12 -2
- package/dist/src/generated/action-output-schemas.json +296 -0
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +1 -0
- package/dist/src/resources/bundles.d.ts +18 -0
- package/dist/src/resources/bundles.js +26 -0
- package/dist/src/resources/futures.d.ts +3 -0
- package/dist/src/resources/futures.js +5 -1
- package/dist/src/resources/messaging-channels.d.ts +83 -0
- package/dist/src/resources/messaging-channels.js +108 -0
- package/dist/src/resources/projects.d.ts +24 -0
- package/dist/src/resources/projects.js +36 -0
- package/dist/src/resources/recipe-create.d.ts +4 -1
- package/dist/src/resources/recipe-create.js +11 -2
- package/dist/src/resources/scenario-authoring.d.ts +52 -0
- package/dist/src/resources/scenario-authoring.js +216 -0
- package/dist/src/resources/scenarios.d.ts +128 -11
- package/dist/src/resources/scenarios.js +273 -43
- package/dist/src/resources/sql.js +3 -3
- package/dist/src/utils/messaging-channel-secrets.d.ts +17 -0
- package/dist/src/utils/messaging-channel-secrets.js +114 -0
- package/package.json +2 -1
- package/plugin.json +1 -1
- package/skills/dataiku-dss/SKILL.md +15 -16
- package/skills/dataiku-dss/references/discovery.md +2 -2
- package/skills/dataiku-dss/references/notifications.md +29 -0
- package/skills/dataiku-dss/references/troubleshooting.md +1 -0
package/dist/src/cli/contract.js
CHANGED
|
@@ -253,6 +253,7 @@ const ALLOWED_CLEANUP_ACTIONS = new Set([
|
|
|
253
253
|
"data-collection delete",
|
|
254
254
|
"plugin delete",
|
|
255
255
|
"connection delete",
|
|
256
|
+
"messaging-channel delete",
|
|
256
257
|
"user delete",
|
|
257
258
|
"group delete",
|
|
258
259
|
]);
|
|
@@ -669,6 +670,9 @@ function inferSideEffect(resource, action) {
|
|
|
669
670
|
}
|
|
670
671
|
if (resource === "install-skill")
|
|
671
672
|
return "write";
|
|
673
|
+
// `send` matches no mutating verb, yet delivers real mail through the channel.
|
|
674
|
+
if (resource === "messaging-channel" && action === "send")
|
|
675
|
+
return "write";
|
|
672
676
|
if (resource === "sql" && action === "query")
|
|
673
677
|
return "write";
|
|
674
678
|
if (resource === "ml-task" && action === "train")
|
|
@@ -735,7 +739,7 @@ function inferSideEffect(resource, action) {
|
|
|
735
739
|
.test(action)
|
|
736
740
|
// Compound actions whose mutating verb is a suffix (e.g. permissions-set,
|
|
737
741
|
// dataset-compute, saved-model external-metadata-put).
|
|
738
|
-
|| /-(set|compute|restore|put)$/.test(action)) {
|
|
742
|
+
|| /-(set|compute|restore|put|add|remove)$/.test(action)) {
|
|
739
743
|
return "write";
|
|
740
744
|
}
|
|
741
745
|
return "read";
|
|
@@ -779,10 +783,16 @@ const STRING_OUTPUT_ACTIONS = new Set([
|
|
|
779
783
|
*/
|
|
780
784
|
const SCOPED_OUTPUT_SHAPES = {
|
|
781
785
|
"folder.contents": "array",
|
|
786
|
+
"scenario.last-runs": "array",
|
|
787
|
+
"scenario.runs-by-date": "array",
|
|
788
|
+
"scenario.trigger-list": "array",
|
|
789
|
+
"scenario.reporter-list": "array",
|
|
790
|
+
"scenario.run-report": "string",
|
|
782
791
|
"plugin.usages": "object",
|
|
783
792
|
"plugin.download": "object",
|
|
784
793
|
"dataset.download": "object",
|
|
785
794
|
"project-library.get": "string",
|
|
795
|
+
"messaging-channel.permissions-get": "array",
|
|
786
796
|
"project-library.diff": "object",
|
|
787
797
|
};
|
|
788
798
|
function inferOutputShape(resource, action) {
|
|
@@ -919,6 +929,11 @@ const EXPLICIT_DESTRUCTIVE_KEYS = {
|
|
|
919
929
|
// MLflow cleanup permanently erases experiment-tracking data.
|
|
920
930
|
"mlflow.garbage-collect": true,
|
|
921
931
|
"mlflow.clean-db": true,
|
|
932
|
+
// Removing a trigger or reporter drops its configuration; no public route restores it.
|
|
933
|
+
"scenario.trigger-remove": true,
|
|
934
|
+
"scenario.reporter-remove": true,
|
|
935
|
+
// A sent mail is delivered to external recipients and cannot be recalled.
|
|
936
|
+
"messaging-channel.send": true,
|
|
922
937
|
};
|
|
923
938
|
function inferDestructiveLevel(resource, sideEffect, action) {
|
|
924
939
|
if (sideEffect !== "write")
|
|
@@ -945,7 +960,8 @@ function inferAsyncKind(resource, action) {
|
|
|
945
960
|
return "job";
|
|
946
961
|
if (resource === "future" && ["get", "peek", "wait", "abort",].includes(action))
|
|
947
962
|
return "future";
|
|
948
|
-
if (resource === "scenario"
|
|
963
|
+
if (resource === "scenario"
|
|
964
|
+
&& ["run", "run-and-wait", "status", "get-run-for-trigger",].includes(action)) {
|
|
949
965
|
return "future";
|
|
950
966
|
}
|
|
951
967
|
if (resource === "user" && ADMIN_SECURITY_FUTURE_ACTIONS[action] === true)
|
|
@@ -1518,7 +1534,7 @@ export function buildAgentContract() {
|
|
|
1518
1534
|
"dss commands run --fields dataset",
|
|
1519
1535
|
"dss commands run --fields dataset.create",
|
|
1520
1536
|
],
|
|
1521
|
-
scopedDiscoveryHint: "Default: resource/action summary. --contains TEXT: top 5 actions by concept. --fields RESOURCE:
|
|
1537
|
+
scopedDiscoveryHint: "Default: resource/action summary. --contains TEXT: top 5 actions by concept. --fields RESOURCE: each action's usage, description, and side effect; RESOURCE.ACTION: one full entry keyed by that path; append .FIELD for nested metadata. Comma-separate paths. --output PATH exports full entries (the full registry without --fields).",
|
|
1522
1538
|
// Accepted by every command and absent from per-entry `flags`; the
|
|
1523
1539
|
// connection flags matter only for commands that call DSS.
|
|
1524
1540
|
globalFlags: [...GLOBAL_AGENT_FLAGS, ...AUTHENTICATED_AGENT_FLAGS,].map((name) => {
|
|
@@ -1545,7 +1561,7 @@ export function buildAgentContract() {
|
|
|
1545
1561
|
failure: "structured-error-object",
|
|
1546
1562
|
failureResultDetailLimitBytes: 65_536,
|
|
1547
1563
|
fieldProjection: "Missing --fields paths: null on stdout; field_projection_missing on stderr.",
|
|
1548
|
-
compactResults: "*.list, job get, dataset get/info, project get: compact; --full/--fields use DSS objects; lists take --contains/--limit (list_truncated warning).",
|
|
1564
|
+
compactResults: "*.list, job get, dataset get/info, project get, scenario get-run/last-runs: compact; --full/--fields use DSS objects; lists take --contains/--limit (list_truncated warning).",
|
|
1549
1565
|
richFailureResults: "doctor/batch/cleanup failures: own compact {ok:false,...} result on stdout and command exit code; no wrapper.",
|
|
1550
1566
|
},
|
|
1551
1567
|
stderr: {
|
package/dist/src/cli/env.d.ts
CHANGED
|
@@ -10,4 +10,10 @@ export declare function envFileProvenance(name: string): EnvFileProvenance | und
|
|
|
10
10
|
export declare function dataikuEnvironmentEnabled(): boolean;
|
|
11
11
|
/** DATAIKU_PROJECT_KEY from the environment, unless `DATAIKU_DISABLE_ENV=1`. */
|
|
12
12
|
export declare function ambientProjectKey(): string | undefined;
|
|
13
|
+
/**
|
|
14
|
+
* `DSS_PRETTY=1` indents stdout JSON. Agent shells that cut long lines (omp at
|
|
15
|
+
* 768 bytes) truncate a one-line result; indented output keeps each line short.
|
|
16
|
+
* Read from the process environment only, never from a `.env` file.
|
|
17
|
+
*/
|
|
18
|
+
export declare function prettyOutputEnabled(): boolean;
|
|
13
19
|
export declare function loadEnvFile(): void;
|
package/dist/src/cli/env.js
CHANGED
|
@@ -23,6 +23,14 @@ export function dataikuEnvironmentEnabled() {
|
|
|
23
23
|
export function ambientProjectKey() {
|
|
24
24
|
return dataikuEnvironmentEnabled() ? process.env.DATAIKU_PROJECT_KEY : undefined;
|
|
25
25
|
}
|
|
26
|
+
/**
|
|
27
|
+
* `DSS_PRETTY=1` indents stdout JSON. Agent shells that cut long lines (omp at
|
|
28
|
+
* 768 bytes) truncate a one-line result; indented output keeps each line short.
|
|
29
|
+
* Read from the process environment only, never from a `.env` file.
|
|
30
|
+
*/
|
|
31
|
+
export function prettyOutputEnabled() {
|
|
32
|
+
return process.env.DSS_PRETTY === "1";
|
|
33
|
+
}
|
|
26
34
|
const allowedEnvKeys = new Set(["NODE_EXTRA_CA_CERTS", "NODE_TLS_REJECT_UNAUTHORIZED",]);
|
|
27
35
|
/**
|
|
28
36
|
* `.env` files are untrusted input: only the CLI's own `DATAIKU_*` variables and
|
package/dist/src/cli/flags.js
CHANGED
|
@@ -76,6 +76,9 @@ export const BOOLEAN_FLAGS = new Set([
|
|
|
76
76
|
"no-auto-rebuild",
|
|
77
77
|
"all-users",
|
|
78
78
|
"with-scenarios",
|
|
79
|
+
"scenarios-only",
|
|
80
|
+
"only-finished",
|
|
81
|
+
"clear",
|
|
79
82
|
"for-everybody",
|
|
80
83
|
"payload-only",
|
|
81
84
|
"allow-same-path",
|
|
@@ -102,6 +105,8 @@ export const BOOLEAN_FLAGS = new Set([
|
|
|
102
105
|
"conda",
|
|
103
106
|
"force",
|
|
104
107
|
"partitioning-folder",
|
|
108
|
+
"plain-text",
|
|
109
|
+
"single-message",
|
|
105
110
|
]);
|
|
106
111
|
export const SHORT_FLAGS = {
|
|
107
112
|
v: "verbose",
|
|
@@ -231,6 +236,24 @@ export const VALUE_FLAGS = new Set([
|
|
|
231
236
|
"repository",
|
|
232
237
|
"request-timeout",
|
|
233
238
|
"params",
|
|
239
|
+
"params-file",
|
|
240
|
+
"frequency",
|
|
241
|
+
"every",
|
|
242
|
+
"hour",
|
|
243
|
+
"minute",
|
|
244
|
+
"days",
|
|
245
|
+
"day-of-month",
|
|
246
|
+
"run-on",
|
|
247
|
+
"start-date",
|
|
248
|
+
"timezone",
|
|
249
|
+
"index",
|
|
250
|
+
"channel",
|
|
251
|
+
"recipient",
|
|
252
|
+
"subject",
|
|
253
|
+
"condition",
|
|
254
|
+
"phase",
|
|
255
|
+
"user",
|
|
256
|
+
"trigger-id",
|
|
234
257
|
"password-env",
|
|
235
258
|
"results-per-page",
|
|
236
259
|
"record-cleanup",
|
|
@@ -324,6 +347,16 @@ export const VALUE_FLAGS = new Set([
|
|
|
324
347
|
"time-variable",
|
|
325
348
|
"timeseries-ids",
|
|
326
349
|
"full-reguess",
|
|
350
|
+
"cc",
|
|
351
|
+
"bcc",
|
|
352
|
+
"subject",
|
|
353
|
+
"body",
|
|
354
|
+
"body-file",
|
|
355
|
+
"attachment",
|
|
356
|
+
"family",
|
|
357
|
+
"permissions",
|
|
358
|
+
"automation-node-id",
|
|
359
|
+
"id",
|
|
327
360
|
]);
|
|
328
361
|
export const REPEATABLE_VALUE_FLAGS = new Set([
|
|
329
362
|
"dataset",
|
|
@@ -337,6 +370,7 @@ export const REPEATABLE_VALUE_FLAGS = new Set([
|
|
|
337
370
|
"replace-input",
|
|
338
371
|
"replace-output",
|
|
339
372
|
"replace-payload-text",
|
|
373
|
+
"attachment",
|
|
340
374
|
]);
|
|
341
375
|
export const KNOWN_LONG_FLAGS = new Set([
|
|
342
376
|
...BOOLEAN_FLAGS,
|
|
@@ -345,6 +345,17 @@ export function cleanupLedgerEntry(resource, action, args, flags, result, projec
|
|
|
345
345
|
cleanup: { argv: ["streaming-endpoint", "delete", id, ...withProject,], },
|
|
346
346
|
};
|
|
347
347
|
}
|
|
348
|
+
case "messaging-channel.create": {
|
|
349
|
+
// DSS echoes the id it allocated; an explicit --id is the fallback.
|
|
350
|
+
const id = stringField(record, ["id",]) ?? flags["id"];
|
|
351
|
+
if (!id)
|
|
352
|
+
return undefined;
|
|
353
|
+
return {
|
|
354
|
+
...base,
|
|
355
|
+
id,
|
|
356
|
+
cleanup: { argv: ["messaging-channel", "delete", id, "--if-exists",], },
|
|
357
|
+
};
|
|
358
|
+
}
|
|
348
359
|
case "meaning.create": {
|
|
349
360
|
const id = args[0];
|
|
350
361
|
return {
|
|
@@ -100,6 +100,11 @@ export const COMPACT_LIST_FIELDS = {
|
|
|
100
100
|
label: field("label", STRING),
|
|
101
101
|
type: field("type", STRING),
|
|
102
102
|
},
|
|
103
|
+
"messaging-channel": {
|
|
104
|
+
id: field("id", STRING),
|
|
105
|
+
type: field("type", STRING),
|
|
106
|
+
family: field("family", STRING),
|
|
107
|
+
},
|
|
103
108
|
};
|
|
104
109
|
/** Discovery output schemas of the compact `RESOURCE.list` defaults. */
|
|
105
110
|
export function compactListOutputSchemas() {
|
package/dist/src/cli/output.d.ts
CHANGED
|
@@ -11,6 +11,8 @@ export declare function pickResultFields(item: unknown, fields: string[]): unkno
|
|
|
11
11
|
* that are absent become null so every row keeps a stable, predictable shape.
|
|
12
12
|
*/
|
|
13
13
|
export declare function projectResultFields(result: unknown, fields: string[], availableFieldNames?: () => string[]): unknown;
|
|
14
|
+
/** One JSON value plus newline for stdout; indented when `DSS_PRETTY=1`. */
|
|
15
|
+
export declare function stdoutJson(value: unknown): string;
|
|
14
16
|
export declare function writeCommandResult(result: unknown): void;
|
|
15
17
|
export declare function addTransientTargetContext(error: unknown, target: string, elapsedMs: number): never;
|
|
16
18
|
export declare function isFailedWaitResult(result: unknown): boolean;
|
package/dist/src/cli/output.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { DataikuError, } from "../errors.js";
|
|
2
|
+
import { prettyOutputEnabled, } from "./env.js";
|
|
2
3
|
let outputFieldProjection;
|
|
3
4
|
export function setOutputFieldProjection(fields) {
|
|
4
5
|
outputFieldProjection = fields;
|
|
@@ -98,12 +99,16 @@ export function projectResultFields(result, fields, availableFieldNames) {
|
|
|
98
99
|
return result.map((item) => pickResultFields(item, fields));
|
|
99
100
|
return pickResultFields(result, fields);
|
|
100
101
|
}
|
|
102
|
+
/** One JSON value plus newline for stdout; indented when `DSS_PRETTY=1`. */
|
|
103
|
+
export function stdoutJson(value) {
|
|
104
|
+
return `${JSON.stringify(value, null, prettyOutputEnabled() ? 2 : undefined)}\n`;
|
|
105
|
+
}
|
|
101
106
|
export function writeCommandResult(result) {
|
|
102
107
|
const projected = outputFieldProjection
|
|
103
108
|
? projectResultFields(result, outputFieldProjection)
|
|
104
109
|
: result;
|
|
105
110
|
flushCliWarnings();
|
|
106
|
-
process.stdout.write(
|
|
111
|
+
process.stdout.write(stdoutJson(projected ?? { ok: true, }));
|
|
107
112
|
}
|
|
108
113
|
export function addTransientTargetContext(error, target, elapsedMs) {
|
|
109
114
|
if (error instanceof DataikuError && error.category === "transient") {
|
|
@@ -200,13 +205,28 @@ export function commandFailureMessage(result) {
|
|
|
200
205
|
const resume = typeof record.resume === "string" ? ` Resume with: ${record.resume}` : "";
|
|
201
206
|
return `Timed out waiting for job ${record.jobId} after ${record.elapsedMs}ms (last known state: ${record.state}); the job is still running in DSS and was not cancelled.${resume}`;
|
|
202
207
|
}
|
|
208
|
+
if (record.timedOut === true) {
|
|
209
|
+
// ML training, scenario runs, futures, code run: the client stopped waiting. Only a
|
|
210
|
+
// result that says `cancelled: false` proves nothing was stopped; `code run` cleans up
|
|
211
|
+
// its throwaway scenario, so its `cleanup` status is what tells.
|
|
212
|
+
const known = typeof record.state === "string"
|
|
213
|
+
? record.state
|
|
214
|
+
: typeof record.outcome === "string"
|
|
215
|
+
? record.outcome
|
|
216
|
+
: undefined;
|
|
217
|
+
const elapsed = typeof record.elapsedMs === "number" ? ` after ${record.elapsedMs}ms` : "";
|
|
218
|
+
const after = record.cancelled === false
|
|
219
|
+
? "the operation was not cancelled and may still be running in DSS."
|
|
220
|
+
: record.cleanup !== undefined
|
|
221
|
+
? "the client stopped waiting; see `cleanup` for what happened to the run."
|
|
222
|
+
: "the client stopped waiting; the operation may still be running in DSS.";
|
|
223
|
+
return `Timed out waiting${elapsed}${known ? ` (last known state: ${known})` : ""}; ${after}`;
|
|
224
|
+
}
|
|
203
225
|
const state = typeof record.state === "string"
|
|
204
226
|
? record.state
|
|
205
227
|
: typeof record.outcome === "string"
|
|
206
228
|
? record.outcome
|
|
207
|
-
:
|
|
208
|
-
? "timed out"
|
|
209
|
-
: undefined;
|
|
229
|
+
: undefined;
|
|
210
230
|
return `Command completed with failed long-running result${state ? `: ${state}` : ""}.`;
|
|
211
231
|
}
|
|
212
232
|
if (isAssertionFailureResult(result)) {
|
package/dist/src/cli/plans.js
CHANGED
|
@@ -10,13 +10,16 @@ import { encodeLibraryPath, PROJECT_LIBRARY_CONCURRENCY_CONTROL, validateLibrary
|
|
|
10
10
|
import { buildRecipeCreateRequest, } from "../resources/recipe-create.js";
|
|
11
11
|
import { modelDiagnosticsBody, } from "../resources/trained-model.js";
|
|
12
12
|
import { encodeGitReferencePath, validateGitReferencePath, } from "../utils/git-reference.js";
|
|
13
|
+
import { sanitizeMessagingChannelSecrets, } from "../utils/messaging-channel-secrets.js";
|
|
13
14
|
import { jobBuildTargetTypeFromFlags, json, jsonInput, num, parseBooleanOption, parseJsonObject, requiredJsonInput, rewritePairsFromFlags, schemaColumnsInput, sha256Hex, stableHash, stringField, textInput, unknownJsonInput, } from "./coerce.js";
|
|
14
15
|
import { parseCodeRunIntegerFlag, resolveCodeInputWithSource, } from "./commands/code.js";
|
|
15
16
|
import { schemaPropagationOptionsFromFlags, } from "./commands/flow.js";
|
|
17
|
+
import { messagingChannelPlanShape, } from "./commands/messaging-channel.js";
|
|
16
18
|
import { mlTaskFieldsFromFlags, mlTaskReguessOptionsFromFlags, } from "./commands/ml-task.js";
|
|
17
19
|
import { deployRunOptionsFromFlags, experimentsDatasetOptionsFromFlags, inferenceInfoFromFlags, } from "./commands/mlflow.js";
|
|
18
20
|
import { projectLibraryPutPayload, } from "./commands/project-library.js";
|
|
19
21
|
import { enqueueRecipeCreateWarnings, recipeCreateOptionsFromFlags, } from "./commands/recipe.js";
|
|
22
|
+
import { scenarioReporterFromFlags, scenarioRunParams, scenarioTriggerFromFlags, } from "./commands/scenario.js";
|
|
20
23
|
import { resolveSqlQueryInvocation, } from "./commands/sql.js";
|
|
21
24
|
import { buildRegistryEntry, splitPackageSpec, } from "./contract.js";
|
|
22
25
|
import { ambientProjectKey, } from "./env.js";
|
|
@@ -1209,7 +1212,7 @@ export function commandPlanShape(resource, action, args, flags, entry, projectKe
|
|
|
1209
1212
|
method: "POST",
|
|
1210
1213
|
endpoint: projectEndpoint(`/scenarios/${encodeURIComponent(id)}/run/`),
|
|
1211
1214
|
identifiers: { id, },
|
|
1212
|
-
payload: {},
|
|
1215
|
+
payload: scenarioRunParams(flags) ?? {},
|
|
1213
1216
|
wait: action === "run-and-wait" || flags["wait"] === true,
|
|
1214
1217
|
};
|
|
1215
1218
|
case "scenario.delete":
|
|
@@ -1230,10 +1233,84 @@ export function commandPlanShape(resource, action, args, flags, entry, projectKe
|
|
|
1230
1233
|
name: args[1],
|
|
1231
1234
|
projectKey,
|
|
1232
1235
|
type,
|
|
1233
|
-
|
|
1236
|
+
...(type === "step_based"
|
|
1237
|
+
? { params: { steps: [], }, triggers: [], reporters: [], }
|
|
1238
|
+
: { params: {}, }),
|
|
1239
|
+
...jsonInput(flags),
|
|
1234
1240
|
},
|
|
1235
1241
|
};
|
|
1236
1242
|
}
|
|
1243
|
+
case "scenario.trigger-add":
|
|
1244
|
+
case "scenario.reporter-add": {
|
|
1245
|
+
const isTrigger = action === "trigger-add";
|
|
1246
|
+
const field = isTrigger ? "triggers" : "reporters";
|
|
1247
|
+
const item = isTrigger
|
|
1248
|
+
? scenarioTriggerFromFlags(flags)
|
|
1249
|
+
: sanitizeMessagingChannelSecrets(scenarioReporterFromFlags(flags));
|
|
1250
|
+
const endpoint = projectEndpoint(`/scenarios/${encodeURIComponent(id)}/`);
|
|
1251
|
+
return {
|
|
1252
|
+
exact: false,
|
|
1253
|
+
reason: `Apply GETs the scenario, appends this element to ${field} (the others are kept), PUTs the full scenario, then GETs it back to verify; the stored element gains DSS-assigned ids.`,
|
|
1254
|
+
method: "PUT",
|
|
1255
|
+
endpoint,
|
|
1256
|
+
identifiers: { id, },
|
|
1257
|
+
payload: item,
|
|
1258
|
+
requests: [
|
|
1259
|
+
{ sequence: 1, method: "GET", endpoint, },
|
|
1260
|
+
{ sequence: 2, method: "PUT", endpoint, payloadEdits: { [field]: { append: item, }, }, },
|
|
1261
|
+
{ sequence: 3, method: "GET", endpoint, },
|
|
1262
|
+
],
|
|
1263
|
+
};
|
|
1264
|
+
}
|
|
1265
|
+
case "scenario.trigger-remove":
|
|
1266
|
+
case "scenario.reporter-remove": {
|
|
1267
|
+
const field = action === "trigger-remove" ? "triggers" : "reporters";
|
|
1268
|
+
const selector = flags["index"] !== undefined
|
|
1269
|
+
? { index: num(flags["index"], "--index"), }
|
|
1270
|
+
: { name: flags["name"], };
|
|
1271
|
+
if ((flags["index"] === undefined) === (flags["name"] === undefined)) {
|
|
1272
|
+
throw new UsageError(`Pass exactly one of --index or --name. Usage: ${entry.usage}`);
|
|
1273
|
+
}
|
|
1274
|
+
const endpoint = projectEndpoint(`/scenarios/${encodeURIComponent(id)}/`);
|
|
1275
|
+
return {
|
|
1276
|
+
exact: false,
|
|
1277
|
+
reason: `Apply GETs the scenario, drops the selected element from ${field} (the others are kept), PUTs the full scenario, then GETs it back to verify.`,
|
|
1278
|
+
method: "PUT",
|
|
1279
|
+
endpoint,
|
|
1280
|
+
identifiers: { id, },
|
|
1281
|
+
payload: selector,
|
|
1282
|
+
requests: [
|
|
1283
|
+
{ sequence: 1, method: "GET", endpoint, },
|
|
1284
|
+
{ sequence: 2, method: "PUT", endpoint, payloadEdits: { [field]: { remove: selector, }, }, },
|
|
1285
|
+
{ sequence: 3, method: "GET", endpoint, },
|
|
1286
|
+
],
|
|
1287
|
+
};
|
|
1288
|
+
}
|
|
1289
|
+
case "scenario.run-as-set": {
|
|
1290
|
+
const user = flags["user"];
|
|
1291
|
+
if ((typeof user === "string") === (flags["clear"] === true)) {
|
|
1292
|
+
throw new UsageError(`Pass exactly one of --user LOGIN or --clear. Usage: ${entry.usage}`);
|
|
1293
|
+
}
|
|
1294
|
+
const endpoint = projectEndpoint(`/scenarios/${encodeURIComponent(id)}/`);
|
|
1295
|
+
return {
|
|
1296
|
+
exact: false,
|
|
1297
|
+
reason: "Apply GETs the scenario, sets (or, with --clear, removes) runAsUser, PUTs the full scenario, then GETs it back to verify.",
|
|
1298
|
+
method: "PUT",
|
|
1299
|
+
endpoint,
|
|
1300
|
+
identifiers: { id, },
|
|
1301
|
+
payload: { runAsUser: typeof user === "string" ? user : null, },
|
|
1302
|
+
requests: [
|
|
1303
|
+
{ sequence: 1, method: "GET", endpoint, },
|
|
1304
|
+
{
|
|
1305
|
+
sequence: 2,
|
|
1306
|
+
method: "PUT",
|
|
1307
|
+
endpoint,
|
|
1308
|
+
payloadEdits: { runAsUser: typeof user === "string" ? user : "<removed>", },
|
|
1309
|
+
},
|
|
1310
|
+
{ sequence: 3, method: "GET", endpoint, },
|
|
1311
|
+
],
|
|
1312
|
+
};
|
|
1313
|
+
}
|
|
1237
1314
|
case "scenario.update":
|
|
1238
1315
|
return {
|
|
1239
1316
|
method: "PUT",
|
|
@@ -1345,6 +1422,21 @@ export function commandPlanShape(resource, action, args, flags, entry, projectKe
|
|
|
1345
1422
|
endpoint: `/public/api/project-deployer/infras/${encodeURIComponent(id)}`,
|
|
1346
1423
|
identifiers: { infraId: id, },
|
|
1347
1424
|
};
|
|
1425
|
+
case "project-deployer.run-test-scenarios": {
|
|
1426
|
+
const nodeFlag = flags["automation-node-id"];
|
|
1427
|
+
const automationNodeId = typeof nodeFlag === "string" && nodeFlag !== "" ? nodeFlag : undefined;
|
|
1428
|
+
return {
|
|
1429
|
+
method: "POST",
|
|
1430
|
+
endpoint: `/public/api/project-deployer/deployments/${encodeURIComponent(id)}/run-test-scenarios${querySuffix({ automationNodeId, })}`,
|
|
1431
|
+
identifiers: { deploymentId: id, },
|
|
1432
|
+
};
|
|
1433
|
+
}
|
|
1434
|
+
case "messaging-channel.create":
|
|
1435
|
+
case "messaging-channel.settings-set":
|
|
1436
|
+
case "messaging-channel.permissions-set":
|
|
1437
|
+
case "messaging-channel.delete":
|
|
1438
|
+
case "messaging-channel.send":
|
|
1439
|
+
return messagingChannelPlanShape(action, args, flags, projectKey);
|
|
1348
1440
|
case "project-deployer.delete-project":
|
|
1349
1441
|
return {
|
|
1350
1442
|
method: "DELETE",
|
|
@@ -32,7 +32,29 @@ export function compactReadOutputSchemas() {
|
|
|
32
32
|
additionalProperties: false,
|
|
33
33
|
properties: { type: STRING, message: STRING, },
|
|
34
34
|
};
|
|
35
|
-
|
|
35
|
+
const triggerSchema = {
|
|
36
|
+
type: "object",
|
|
37
|
+
additionalProperties: false,
|
|
38
|
+
properties: { type: STRING, name: STRING, },
|
|
39
|
+
};
|
|
40
|
+
const failureSchema = {
|
|
41
|
+
type: "object",
|
|
42
|
+
additionalProperties: false,
|
|
43
|
+
properties: {
|
|
44
|
+
stepId: STRING,
|
|
45
|
+
jobId: STRING,
|
|
46
|
+
dataset: STRING,
|
|
47
|
+
recipe: STRING,
|
|
48
|
+
inputs: { type: "array", items: { type: "string", }, },
|
|
49
|
+
message: STRING,
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
const nextSchema = {
|
|
53
|
+
type: "array",
|
|
54
|
+
description: "Next commands to run, each as an argv array.",
|
|
55
|
+
items: { type: "array", items: STRING, },
|
|
56
|
+
};
|
|
57
|
+
const schemas = {
|
|
36
58
|
"job.get": {
|
|
37
59
|
type: "object",
|
|
38
60
|
additionalProperties: false,
|
|
@@ -110,5 +132,74 @@ export function compactReadOutputSchemas() {
|
|
|
110
132
|
lastModifiedBy: STRING,
|
|
111
133
|
},
|
|
112
134
|
},
|
|
135
|
+
"scenario.get-run": {
|
|
136
|
+
type: "object",
|
|
137
|
+
additionalProperties: false,
|
|
138
|
+
required: ["runId", "steps",],
|
|
139
|
+
properties: {
|
|
140
|
+
runId: STRING,
|
|
141
|
+
scenarioId: STRING,
|
|
142
|
+
projectKey: STRING,
|
|
143
|
+
outcome: STRING,
|
|
144
|
+
start: NUMBER,
|
|
145
|
+
end: NUMBER,
|
|
146
|
+
durationMs: NUMBER,
|
|
147
|
+
trigger: triggerSchema,
|
|
148
|
+
steps: {
|
|
149
|
+
type: "array",
|
|
150
|
+
items: {
|
|
151
|
+
type: "object",
|
|
152
|
+
additionalProperties: false,
|
|
153
|
+
properties: {
|
|
154
|
+
id: STRING,
|
|
155
|
+
name: STRING,
|
|
156
|
+
type: STRING,
|
|
157
|
+
outcome: STRING,
|
|
158
|
+
message: STRING,
|
|
159
|
+
datasets: {
|
|
160
|
+
type: "array",
|
|
161
|
+
items: {
|
|
162
|
+
type: "object",
|
|
163
|
+
additionalProperties: false,
|
|
164
|
+
properties: { dataset: STRING, projectKey: STRING, partition: STRING, outcome: STRING, },
|
|
165
|
+
},
|
|
166
|
+
},
|
|
167
|
+
jobs: {
|
|
168
|
+
type: "array",
|
|
169
|
+
items: {
|
|
170
|
+
type: "object",
|
|
171
|
+
additionalProperties: false,
|
|
172
|
+
properties: { jobId: STRING, outcome: STRING, message: STRING, },
|
|
173
|
+
},
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
failure: failureSchema,
|
|
179
|
+
next: nextSchema,
|
|
180
|
+
hint: {
|
|
181
|
+
type: "string",
|
|
182
|
+
description: "Edit-and-rerun commands when the failed recipe is known.",
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
"scenario.last-runs": {
|
|
187
|
+
type: "array",
|
|
188
|
+
items: {
|
|
189
|
+
type: "object",
|
|
190
|
+
additionalProperties: false,
|
|
191
|
+
required: ["runId",],
|
|
192
|
+
properties: {
|
|
193
|
+
runId: STRING,
|
|
194
|
+
outcome: STRING,
|
|
195
|
+
start: NUMBER,
|
|
196
|
+
end: NUMBER,
|
|
197
|
+
trigger: triggerSchema,
|
|
198
|
+
failure: { type: "object", additionalProperties: false, properties: { message: STRING, }, },
|
|
199
|
+
next: nextSchema,
|
|
200
|
+
},
|
|
201
|
+
},
|
|
202
|
+
},
|
|
113
203
|
};
|
|
204
|
+
return { ...schemas, "scenario.runs-by-date": schemas["scenario.last-runs"], };
|
|
114
205
|
}
|
|
@@ -1,6 +1,24 @@
|
|
|
1
|
+
type Item = Record<string, unknown>;
|
|
2
|
+
/** The failed activity of a job: the recipe that failed and the datasets it read. */
|
|
3
|
+
export interface FailedActivity {
|
|
4
|
+
recipe: string;
|
|
5
|
+
inputs: string[];
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Failure diagnosis of a raw `scenario get-run` report: the first failure
|
|
9
|
+
* (`{ stepId, jobId, dataset, message }`) and the next command(s) to run as
|
|
10
|
+
* argv arrays. With the failed recipe known, `hint` names the edit-and-rerun
|
|
11
|
+
* loop, so the agent does not look up the write commands. Empty when the run did not fail.
|
|
12
|
+
*/
|
|
13
|
+
export declare function scenarioRunDiagnosis(details: unknown, activity?: FailedActivity): {
|
|
14
|
+
failure?: Item;
|
|
15
|
+
next?: string[][];
|
|
16
|
+
hint?: string;
|
|
17
|
+
};
|
|
1
18
|
/**
|
|
2
19
|
* Compact a command result for agents: `*.list` items (filter, cap, compact
|
|
3
|
-
* fields) and the
|
|
20
|
+
* fields) and the large read commands. `--full` and `--fields` bypass
|
|
4
21
|
* the read shapers so the DSS object (or a projection of it) is returned.
|
|
5
22
|
*/
|
|
6
23
|
export declare function shapeCommandResult(resource: string, action: string, result: unknown, flags: Record<string, string | boolean>): unknown;
|
|
24
|
+
export {};
|