dataiku-sdk 3.6.1 → 3.8.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.
Files changed (139) hide show
  1. package/README.md +14 -6
  2. package/bin/bun-version.js +14 -0
  3. package/bin/dss.js +11 -15
  4. package/dist/build-metadata.json +1 -1
  5. package/dist/packages/types/src/index.d.ts +114 -5
  6. package/dist/packages/types/src/index.js +75 -2
  7. package/dist/src/cli/coerce.d.ts +2 -0
  8. package/dist/src/cli/coerce.js +20 -16
  9. package/dist/src/cli/command-syntax.json +3369 -144
  10. package/dist/src/cli/commands/analysis.js +19 -1
  11. package/dist/src/cli/commands/bundle.js +22 -0
  12. package/dist/src/cli/commands/connection.js +26 -2
  13. package/dist/src/cli/commands/data-quality.js +33 -1
  14. package/dist/src/cli/commands/dataset.js +76 -9
  15. package/dist/src/cli/commands/discussion.js +15 -0
  16. package/dist/src/cli/commands/doctor.js +1 -1
  17. package/dist/src/cli/commands/flow-zone.js +241 -46
  18. package/dist/src/cli/commands/flow.d.ts +5 -0
  19. package/dist/src/cli/commands/flow.js +57 -0
  20. package/dist/src/cli/commands/future.js +8 -0
  21. package/dist/src/cli/commands/index.js +6 -0
  22. package/dist/src/cli/commands/job.js +44 -6
  23. package/dist/src/cli/commands/metrics.js +21 -1
  24. package/dist/src/cli/commands/ml-task.d.ts +5 -0
  25. package/dist/src/cli/commands/ml-task.js +86 -16
  26. package/dist/src/cli/commands/mlflow.d.ts +11 -0
  27. package/dist/src/cli/commands/mlflow.js +121 -0
  28. package/dist/src/cli/commands/plugin.js +5 -11
  29. package/dist/src/cli/commands/project-deployer.js +70 -0
  30. package/dist/src/cli/commands/project-library.js +2 -5
  31. package/dist/src/cli/commands/project.js +8 -0
  32. package/dist/src/cli/commands/recipe.d.ts +13 -0
  33. package/dist/src/cli/commands/recipe.js +130 -7
  34. package/dist/src/cli/commands/saved-model.d.ts +1 -1
  35. package/dist/src/cli/commands/saved-model.js +9 -76
  36. package/dist/src/cli/commands/streaming-endpoint.js +30 -1
  37. package/dist/src/cli/commands/webapp.js +8 -0
  38. package/dist/src/cli/commands/wiki.js +78 -0
  39. package/dist/src/cli/commands/workspace.js +8 -0
  40. package/dist/src/cli/contract.d.ts +16 -15
  41. package/dist/src/cli/contract.js +150 -3407
  42. package/dist/src/cli/doctor.d.ts +13 -0
  43. package/dist/src/cli/doctor.js +43 -1
  44. package/dist/src/cli/flags.d.ts +14 -1
  45. package/dist/src/cli/flags.js +106 -8
  46. package/dist/src/cli/helpers/app-successor.js +1 -2
  47. package/dist/src/cli/helpers/dataset.d.ts +12 -0
  48. package/dist/src/cli/helpers/dataset.js +36 -0
  49. package/dist/src/cli/helpers/documentation.d.ts +21 -0
  50. package/dist/src/cli/helpers/documentation.js +53 -0
  51. package/dist/src/cli/helpers/flow-zone.d.ts +21 -0
  52. package/dist/src/cli/helpers/flow-zone.js +144 -4
  53. package/dist/src/cli/helpers/trained-model.d.ts +26 -0
  54. package/dist/src/cli/helpers/trained-model.js +144 -0
  55. package/dist/src/cli/list-output.d.ts +7 -0
  56. package/dist/src/cli/list-output.js +77 -0
  57. package/dist/src/cli/list-shapes.d.ts +21 -0
  58. package/dist/src/cli/list-shapes.js +111 -0
  59. package/dist/src/cli/output-schemas.d.ts +0 -14
  60. package/dist/src/cli/output-schemas.js +4 -7
  61. package/dist/src/cli/output.d.ts +0 -1
  62. package/dist/src/cli/output.js +33 -19
  63. package/dist/src/cli/plans.d.ts +14 -0
  64. package/dist/src/cli/plans.js +3740 -0
  65. package/dist/src/cli/types.d.ts +2 -0
  66. package/dist/src/cli/usage.d.ts +7 -0
  67. package/dist/src/cli/usage.js +20 -1
  68. package/dist/src/cli/version.d.ts +2 -2
  69. package/dist/src/cli/version.js +2 -2
  70. package/dist/src/cli.js +137 -115
  71. package/dist/src/client.d.ts +52 -43
  72. package/dist/src/client.js +267 -96
  73. package/dist/src/errors.d.ts +22 -2
  74. package/dist/src/errors.js +49 -50
  75. package/dist/src/generated/action-output-schemas.json +345 -89
  76. package/dist/src/index.d.ts +5 -1
  77. package/dist/src/index.js +3 -0
  78. package/dist/src/resources/analyses.d.ts +8 -0
  79. package/dist/src/resources/analyses.js +13 -1
  80. package/dist/src/resources/bundles.d.ts +34 -0
  81. package/dist/src/resources/bundles.js +67 -0
  82. package/dist/src/resources/connections.d.ts +9 -0
  83. package/dist/src/resources/connections.js +15 -0
  84. package/dist/src/resources/data-quality.d.ts +20 -0
  85. package/dist/src/resources/data-quality.js +30 -0
  86. package/dist/src/resources/dataset-create.d.ts +38 -0
  87. package/dist/src/resources/dataset-create.js +135 -0
  88. package/dist/src/resources/datasets.d.ts +46 -15
  89. package/dist/src/resources/datasets.js +120 -112
  90. package/dist/src/resources/discussions.d.ts +5 -0
  91. package/dist/src/resources/discussions.js +7 -0
  92. package/dist/src/resources/documentation.d.ts +25 -0
  93. package/dist/src/resources/documentation.js +16 -0
  94. package/dist/src/resources/flow-zones.d.ts +29 -3
  95. package/dist/src/resources/flow-zones.js +53 -3
  96. package/dist/src/resources/flow.d.ts +48 -0
  97. package/dist/src/resources/flow.js +65 -0
  98. package/dist/src/resources/futures.d.ts +23 -0
  99. package/dist/src/resources/futures.js +32 -0
  100. package/dist/src/resources/jobs.d.ts +34 -0
  101. package/dist/src/resources/jobs.js +170 -3
  102. package/dist/src/resources/metrics.d.ts +10 -0
  103. package/dist/src/resources/metrics.js +10 -0
  104. package/dist/src/resources/ml-tasks.d.ts +65 -2
  105. package/dist/src/resources/ml-tasks.js +102 -28
  106. package/dist/src/resources/mlflow-extension.d.ts +73 -0
  107. package/dist/src/resources/mlflow-extension.js +105 -0
  108. package/dist/src/resources/projects.d.ts +15 -0
  109. package/dist/src/resources/projects.js +18 -3
  110. package/dist/src/resources/recipe-create.d.ts +79 -0
  111. package/dist/src/resources/recipe-create.js +454 -0
  112. package/dist/src/resources/recipes.d.ts +28 -29
  113. package/dist/src/resources/recipes.js +201 -267
  114. package/dist/src/resources/saved-models.d.ts +10 -6
  115. package/dist/src/resources/saved-models.js +16 -14
  116. package/dist/src/resources/scenarios.js +8 -14
  117. package/dist/src/resources/sql.js +52 -13
  118. package/dist/src/resources/streaming-endpoints.d.ts +12 -0
  119. package/dist/src/resources/streaming-endpoints.js +15 -0
  120. package/dist/src/resources/trained-model.d.ts +60 -0
  121. package/dist/src/resources/trained-model.js +98 -0
  122. package/dist/src/resources/webapps.d.ts +8 -0
  123. package/dist/src/resources/webapps.js +10 -0
  124. package/dist/src/resources/wiki.d.ts +52 -1
  125. package/dist/src/resources/wiki.js +96 -0
  126. package/dist/src/resources/workspaces.d.ts +2 -0
  127. package/dist/src/resources/workspaces.js +4 -0
  128. package/dist/src/utils/flow-analysis.js +4 -0
  129. package/dist/src/utils/response-file.js +20 -9
  130. package/dist/src/utils/secret-sanitize.d.ts +7 -0
  131. package/dist/src/utils/secret-sanitize.js +46 -0
  132. package/package.json +25 -26
  133. package/plugin.json +1 -1
  134. package/skills/dataiku-dss/SKILL.md +1 -1
  135. package/skills/dataiku-dss/references/authentication.md +3 -1
  136. package/skills/dataiku-dss/references/coding.md +1 -0
  137. package/skills/dataiku-dss/references/discovery.md +4 -6
  138. package/skills/dataiku-dss/references/flow-maps.md +2 -2
  139. package/skills/dataiku-dss/references/troubleshooting.md +3 -2
@@ -68,11 +68,24 @@ export interface DoctorResult {
68
68
  tlsVerify: "strict" | "disabled";
69
69
  caCert: "default" | "custom";
70
70
  };
71
+ identity?: DoctorIdentity;
71
72
  permissions?: DoctorPermissions;
72
73
  permissionDetails?: Partial<Record<DoctorPermissionKey, Record<string, unknown>>>;
73
74
  fixtures?: DoctorFixtures;
74
75
  environment?: DoctorEnvironment;
75
76
  }
77
+ /**
78
+ * The identity a DSS API key acts as, from `GET /public/api/auth/info`
79
+ * (no admin privilege required). Explains unexplained 403s: a personal key
80
+ * acts as its owner, a global key shows up as an `api:<id>` identity.
81
+ * Carries no secret material.
82
+ */
83
+ export interface DoctorIdentity {
84
+ authSource?: string;
85
+ authIdentifier?: string;
86
+ groups?: string[];
87
+ userProfile?: string;
88
+ }
76
89
  export declare function errorDetails(error: unknown): Record<string, unknown>;
77
90
  export declare function firstStringField(items: unknown[] | undefined, fields: string[]): string | null;
78
91
  export declare function integrationFlag(name: string): boolean;
@@ -11,6 +11,8 @@ export function errorDetails(error) {
11
11
  retryable: error.retryable,
12
12
  status: error.status,
13
13
  statusText: error.statusText,
14
+ message: error.message,
15
+ retryHint: error.retryHint,
14
16
  };
15
17
  }
16
18
  return { message: error instanceof Error ? error.message : String(error), };
@@ -49,6 +51,34 @@ export function doctorEnvironment(projectKey, versionInfo) {
49
51
  },
50
52
  };
51
53
  }
54
+ /**
55
+ * Identity fields this doctor version reports, read from the documented
56
+ * `GET /public/api/auth/info` payload. Everything is optional: the field set
57
+ * varies across DSS versions and absent fields stay absent.
58
+ */
59
+ function doctorIdentityFromAuthInfo(raw) {
60
+ if (!raw || typeof raw !== "object" || Array.isArray(raw))
61
+ return undefined;
62
+ const record = raw;
63
+ const groups = Array.isArray(record["groups"])
64
+ ? record["groups"].filter((g) => typeof g === "string")
65
+ : undefined;
66
+ const authSource = typeof record["authSource"] === "string" ? record["authSource"] : undefined;
67
+ const authIdentifier = typeof record["authIdentifier"] === "string"
68
+ ? record["authIdentifier"]
69
+ : undefined;
70
+ const userProfile = typeof record["userProfile"] === "string" ? record["userProfile"] : undefined;
71
+ if (authSource === undefined && authIdentifier === undefined && userProfile === undefined
72
+ && (groups === undefined || groups.length === 0)) {
73
+ return undefined;
74
+ }
75
+ return {
76
+ ...(authSource !== undefined ? { authSource, } : {}),
77
+ ...(authIdentifier !== undefined ? { authIdentifier, } : {}),
78
+ ...(groups !== undefined && groups.length > 0 ? { groups, } : {}),
79
+ ...(userProfile !== undefined ? { userProfile, } : {}),
80
+ };
81
+ }
52
82
  export function permissionStatusForError(error) {
53
83
  if (error instanceof DataikuError) {
54
84
  if (error.status === 401 || error.status === 403 || error.status === 404)
@@ -261,6 +291,7 @@ export async function runDoctor(flags) {
261
291
  });
262
292
  let accessibleProjects;
263
293
  let environmentVersion;
294
+ let identity;
264
295
  if (credentialsOk) {
265
296
  const requestTimeoutMs = num(flags["request-timeout"], "--request-timeout");
266
297
  const retryMaxAttempts = num(flags["retries"], "--retries");
@@ -318,6 +349,12 @@ export async function runDoctor(flags) {
318
349
  details: errorDetails(error),
319
350
  });
320
351
  }
352
+ // Which principal the key acts as (personal vs global key, groups) explains
353
+ // 403s on objects the user's UI profile can use. Diagnostic only: an
354
+ // unanswered /auth/info (older DSS) never fails doctor.
355
+ if (accessibleProjects) {
356
+ identity = await client.get("/public/api/auth/info").then(doctorIdentityFromAuthInfo, () => undefined);
357
+ }
321
358
  if (projectKey) {
322
359
  try {
323
360
  const project = await client.projects.get(projectKey);
@@ -341,7 +378,12 @@ export async function runDoctor(flags) {
341
378
  }
342
379
  }
343
380
  }
344
- const result = { ok: checks.every((check) => check.ok), checks, context, };
381
+ const result = {
382
+ ok: checks.every((check) => check.ok),
383
+ checks,
384
+ context,
385
+ ...(identity ? { identity, } : {}),
386
+ };
345
387
  if (flags["capabilities"] === true && credentialsOk) {
346
388
  const requestTimeoutMs = num(flags["request-timeout"], "--request-timeout");
347
389
  const retryMaxAttempts = num(flags["retries"], "--retries") ?? 1;
@@ -1,3 +1,9 @@
1
+ /**
2
+ * Positional arguments scanned with the same flag grammar as `parseArgs`, so
3
+ * error reporting can recover the invoked resource/action without depending
4
+ * on the command registry being loaded.
5
+ */
6
+ export declare function rawPositionals(argv: string[]): string[];
1
7
  /** Planning wins dispatch; dryRun remains set for combined plan metadata. */
2
8
  export declare function executionMode(flags: Record<string, string | boolean>): {
3
9
  readonly plan: boolean;
@@ -10,8 +16,15 @@ export declare const FLAG_ALIASES: Record<string, string>;
10
16
  export declare const VALUE_FLAGS: Set<string>;
11
17
  export declare const REPEATABLE_VALUE_FLAGS: Set<string>;
12
18
  export declare const KNOWN_LONG_FLAGS: Set<string>;
13
- export declare function normalizeLongFlag(rawFlagName: string): string;
19
+ export declare function normalizeLongFlag(rawFlagName: string, argv: string[]): string;
14
20
  export declare function isNegativeNumberToken(value: string): boolean;
21
+ /**
22
+ * Whether the token after a value flag is that flag's value rather than the
23
+ * next flag. `-` (stdin), negative numbers, and anything not flag-shaped
24
+ * qualify, so a SQL value beginning with a `-- comment` is a value; `--` alone
25
+ * and `--flag`/`--flag=x` are not.
26
+ */
27
+ export declare function isFlagValueToken(token: string): boolean;
15
28
  export declare function requireFlagValue(flagLabel: string, next: string | undefined): string;
16
29
  export declare function setParsedFlagValue(flags: Record<string, string | boolean>, flagName: string, value: string): void;
17
30
  export interface ParsedArgs {
@@ -1,5 +1,40 @@
1
1
  import { parseBooleanOption, } from "./coerce.js";
2
- import { unsupportedHelpFlag, UsageError, } from "./usage.js";
2
+ import { unknownFlagError, unsupportedHelpFlag, UsageError, } from "./usage.js";
3
+ /**
4
+ * Positional arguments scanned with the same flag grammar as `parseArgs`, so
5
+ * error reporting can recover the invoked resource/action without depending
6
+ * on the command registry being loaded.
7
+ */
8
+ export function rawPositionals(argv) {
9
+ const positionals = [];
10
+ for (let index = 0; index < argv.length; index++) {
11
+ const arg = argv[index];
12
+ if (arg === "--") {
13
+ positionals.push(...argv.slice(index + 1));
14
+ break;
15
+ }
16
+ if (arg.startsWith("--")) {
17
+ const name = arg.slice(2).split("=")[0] ?? "";
18
+ const canonical = FLAG_ALIASES[name] ?? name;
19
+ if (!arg.includes("=") && VALUE_FLAGS.has(canonical))
20
+ index++;
21
+ continue;
22
+ }
23
+ if (arg.length === 2 && arg[0] === "-" && arg[1] !== "-") {
24
+ const long = SHORT_FLAGS[arg[1]];
25
+ if (long && VALUE_FLAGS.has(long))
26
+ index++;
27
+ continue;
28
+ }
29
+ positionals.push(arg);
30
+ }
31
+ return positionals;
32
+ }
33
+ /** Unknown flags name the invoked command, so the error carries its usage line. */
34
+ function commandUnknownFlagError(flagLabel, argv) {
35
+ const [resource, action,] = rawPositionals(argv);
36
+ return unknownFlagError(flagLabel, resource, action);
37
+ }
3
38
  /** Planning wins dispatch; dryRun remains set for combined plan metadata. */
4
39
  export function executionMode(flags) {
5
40
  return {
@@ -31,15 +66,22 @@ export const BOOLEAN_FLAGS = new Set([
31
66
  "if-exists",
32
67
  "no-wait",
33
68
  "force-rebuild",
69
+ "auto-update-schema",
34
70
  "latest",
71
+ "full",
35
72
  "copy-output-settings",
36
73
  "copy-permissions",
37
74
  "continue-on-error",
38
75
  "no-backup",
76
+ "no-auto-rebuild",
77
+ "all-users",
78
+ "with-scenarios",
79
+ "for-everybody",
39
80
  "payload-only",
40
81
  "allow-same-path",
41
82
  "sync",
42
83
  "validate-objects",
84
+ "recreate-on-move",
43
85
  "errors-only",
44
86
  "keep",
45
87
  "full-log",
@@ -182,6 +224,8 @@ export const VALUE_FLAGS = new Set([
182
224
  "render",
183
225
  "prediction-type",
184
226
  "project-key",
227
+ "query",
228
+ "query-file",
185
229
  "recipe",
186
230
  "reference",
187
231
  "repository",
@@ -249,6 +293,37 @@ export const VALUE_FLAGS = new Set([
249
293
  "full-class-name",
250
294
  "include-libs",
251
295
  "archive",
296
+ "stop-at",
297
+ "mark-ok",
298
+ "template-file",
299
+ "group-by",
300
+ "aggregate",
301
+ "order-by",
302
+ "rename",
303
+ "fill-empty",
304
+ "formula",
305
+ "filter",
306
+ "drop-columns",
307
+ "keep-columns",
308
+ "columns",
309
+ "format-option",
310
+ "bundle-id",
311
+ "archive-path",
312
+ "project-folder",
313
+ "classes",
314
+ "version-id",
315
+ "evaluation-dataset",
316
+ "experiments",
317
+ "view-type",
318
+ "format",
319
+ "kind",
320
+ "features",
321
+ "sample-size",
322
+ "random-state",
323
+ "n-jobs",
324
+ "time-variable",
325
+ "timeseries-ids",
326
+ "full-reguess",
252
327
  ]);
253
328
  export const REPEATABLE_VALUE_FLAGS = new Set([
254
329
  "dataset",
@@ -269,21 +344,44 @@ export const KNOWN_LONG_FLAGS = new Set([
269
344
  ...Object.keys(FLAG_ALIASES),
270
345
  ...Object.values(FLAG_ALIASES),
271
346
  ]);
272
- export function normalizeLongFlag(rawFlagName) {
347
+ export function normalizeLongFlag(rawFlagName, argv) {
273
348
  if (rawFlagName === "help")
274
349
  throw unsupportedHelpFlag();
275
350
  const flagName = FLAG_ALIASES[rawFlagName] ?? rawFlagName;
276
351
  if (!KNOWN_LONG_FLAGS.has(rawFlagName) && !KNOWN_LONG_FLAGS.has(flagName)) {
277
- throw new UsageError(`Unknown flag: --${rawFlagName}`, "unknown_flag");
352
+ throw commandUnknownFlagError(`--${rawFlagName}`, argv);
278
353
  }
279
354
  return flagName;
280
355
  }
281
356
  export function isNegativeNumberToken(value) {
282
357
  return value.startsWith("-") && Number.isFinite(Number(value));
283
358
  }
359
+ /** `--name` or `--name=value`: a token that parses as a long flag. */
360
+ const LONG_FLAG_SHAPE = /^--[A-Za-z][A-Za-z0-9-]*(?:=|$)/;
361
+ /**
362
+ * Whether the token after a value flag is that flag's value rather than the
363
+ * next flag. `-` (stdin), negative numbers, and anything not flag-shaped
364
+ * qualify, so a SQL value beginning with a `-- comment` is a value; `--` alone
365
+ * and `--flag`/`--flag=x` are not.
366
+ */
367
+ export function isFlagValueToken(token) {
368
+ if (token === "-" || isNegativeNumberToken(token))
369
+ return true;
370
+ if (!token.startsWith("-"))
371
+ return true;
372
+ return token.startsWith("--") && token !== "--" && !LONG_FLAG_SHAPE.test(token);
373
+ }
284
374
  export function requireFlagValue(flagLabel, next) {
285
- if (next === undefined || (next !== "-" && next.startsWith("-") && !isNegativeNumberToken(next))) {
286
- throw new UsageError(`Flag ${flagLabel} requires a value.`, "missing_required_flag");
375
+ if (next === undefined || !isFlagValueToken(next)) {
376
+ const inlineForm = flagLabel.startsWith("--") ? `${flagLabel}=VALUE` : undefined;
377
+ const hint = next === undefined || !next.startsWith("-")
378
+ ? undefined
379
+ : flagLabel === "--sql"
380
+ ? 'A SQL value that starts with `--` (a comment) can be passed as --sql="-- ...", from a file with --sql-file PATH, or on stdin with --stdin.'
381
+ : inlineForm
382
+ ? `If the value itself starts with \`-\`, pass it as ${inlineForm}.`
383
+ : undefined;
384
+ throw new UsageError(`Flag ${flagLabel} requires a value.`, "missing_required_flag", hint);
287
385
  }
288
386
  return next;
289
387
  }
@@ -309,7 +407,7 @@ export function parseArgs(argv) {
309
407
  const eqIdx = arg.indexOf("=");
310
408
  if (eqIdx !== -1) {
311
409
  const raw = arg.slice(2, eqIdx);
312
- const flagName = normalizeLongFlag(raw);
410
+ const flagName = normalizeLongFlag(raw, argv);
313
411
  const value = arg.slice(eqIdx + 1);
314
412
  if (BOOLEAN_FLAGS.has(flagName)) {
315
413
  flags[flagName] = parseBooleanOption(value, `--${flagName}`);
@@ -320,7 +418,7 @@ export function parseArgs(argv) {
320
418
  }
321
419
  else {
322
420
  const rawFlagName = arg.slice(2);
323
- const flagName = normalizeLongFlag(rawFlagName);
421
+ const flagName = normalizeLongFlag(rawFlagName, argv);
324
422
  if (BOOLEAN_FLAGS.has(flagName)) {
325
423
  flags[flagName] = true;
326
424
  }
@@ -346,7 +444,7 @@ export function parseArgs(argv) {
346
444
  else {
347
445
  if (arg[1] === "h")
348
446
  throw unsupportedHelpFlag();
349
- throw new UsageError(`Unknown flag: -${arg[1]}`, "unknown_flag");
447
+ throw commandUnknownFlagError(`-${arg[1]}`, argv);
350
448
  }
351
449
  }
352
450
  else {
@@ -1,4 +1,3 @@
1
- import { randomUUID, } from "node:crypto";
2
1
  import { DataikuError, } from "../../errors.js";
3
2
  import { projectIncarnationHash, } from "../../utils/project-incarnation.js";
4
3
  import { stableHash, stringField, } from "../coerce.js";
@@ -26,7 +25,7 @@ export const VISUAL_UI_GATE = {
26
25
  * probed for absence and is never retried under an alternate key.
27
26
  */
28
27
  export function generatedInstanceKey() {
29
- return `APP_${randomUUID().replace(/-/g, "").toUpperCase()}`;
28
+ return `APP_${crypto.randomUUID().replace(/-/g, "").toUpperCase()}`;
30
29
  }
31
30
  /**
32
31
  * DSS answers the app-manifest probe with 400 ("neither an app template nor an
@@ -1,2 +1,14 @@
1
1
  import type { DatasetDetails } from "../../schemas.js";
2
+ export interface DatasetSqlSourceFlags {
3
+ table?: string;
4
+ dbSchema?: string;
5
+ catalog?: string;
6
+ query?: string;
7
+ }
8
+ /**
9
+ * The SQL source of `dataset create` (`--table [--schema S] [--catalog C]` or
10
+ * `--query SQL`/`--query-file PATH`), validated against the dataset type.
11
+ * Empty when no SQL flag is given.
12
+ */
13
+ export declare function datasetSqlSourceFromFlags(flags: Record<string, string | boolean>, dsType: string): DatasetSqlSourceFlags;
2
14
  export declare function datasetSourceSummary(details: DatasetDetails): Record<string, unknown>;
@@ -1,3 +1,39 @@
1
+ import { assertSqlDatasetSource, } from "../../resources/dataset-create.js";
2
+ import { readInputText, stripUtf8Bom, } from "../coerce.js";
3
+ import { UsageError, } from "../usage.js";
4
+ /**
5
+ * The SQL source of `dataset create` (`--table [--schema S] [--catalog C]` or
6
+ * `--query SQL`/`--query-file PATH`), validated against the dataset type.
7
+ * Empty when no SQL flag is given.
8
+ */
9
+ export function datasetSqlSourceFromFlags(flags, dsType) {
10
+ const text = (flag) => {
11
+ const value = flags[flag];
12
+ if (value === undefined)
13
+ return undefined;
14
+ if (typeof value !== "string") {
15
+ throw new UsageError(`--${flag} requires a value.`, "missing_required_flag");
16
+ }
17
+ return value;
18
+ };
19
+ if (flags["query"] !== undefined && flags["query-file"] !== undefined) {
20
+ throw new UsageError("Conflicting input sources: --query, --query-file. Provide exactly one.", "conflicting_input_sources", undefined, { sources: ["query", "query-file",], });
21
+ }
22
+ const queryFile = text("query-file");
23
+ const inline = text("query");
24
+ const source = {
25
+ ...(text("table") !== undefined ? { table: text("table"), } : {}),
26
+ ...(text("schema") !== undefined ? { dbSchema: text("schema"), } : {}),
27
+ ...(text("catalog") !== undefined ? { catalog: text("catalog"), } : {}),
28
+ ...(queryFile !== undefined
29
+ ? { query: stripUtf8Bom(readInputText(queryFile, "--query-file")), }
30
+ : inline !== undefined
31
+ ? { query: inline, }
32
+ : {}),
33
+ };
34
+ assertSqlDatasetSource(dsType, source);
35
+ return source;
36
+ }
1
37
  export function datasetSourceSummary(details) {
2
38
  const params = details.params ?? {};
3
39
  return {
@@ -0,0 +1,21 @@
1
+ import type { DataikuClient } from "../../client.js";
2
+ import type { DocumentationTemplate } from "../../resources/documentation.js";
3
+ import type { DssTask, FutureWaitOptions } from "../../resources/futures.js";
4
+ import type { FutureWaitResult } from "../../schemas.js";
5
+ type Flags = Record<string, string | boolean>;
6
+ /** Documentation template from flags: --template-file, or --folder with --path, or the DSS default. */
7
+ export declare function documentationTemplateFromFlags(flags: Flags): DocumentationTemplate;
8
+ /** `--poll-interval` / `--timeout` for commands that wait on a DSS task. */
9
+ export declare function taskWaitOptions(flags: Flags): FutureWaitOptions;
10
+ /**
11
+ * Shared `generate-documentation` flow: return the started task; with
12
+ * --wait, its final state; with --output PATH, wait and download the docx
13
+ * named by the result's `exportId`. A failed or timed-out generation carries
14
+ * no exportId, so its state is returned instead.
15
+ */
16
+ export declare function runDocumentationCommand(client: DataikuClient, flags: Flags, task: DssTask, download: (exportId: string) => Promise<Response>): Promise<DssTask | FutureWaitResult | {
17
+ path: string;
18
+ bytes: number;
19
+ exportId: string;
20
+ }>;
21
+ export {};
@@ -0,0 +1,53 @@
1
+ import { writeResponseToFile, } from "../../utils/response-file.js";
2
+ import { num, } from "../coerce.js";
3
+ import { UsageError, } from "../usage.js";
4
+ /** Documentation template from flags: --template-file, or --folder with --path, or the DSS default. */
5
+ export function documentationTemplateFromFlags(flags) {
6
+ const file = flags["template-file"];
7
+ const folder = flags["folder"];
8
+ const path = flags["path"];
9
+ if (typeof file === "string" && (folder !== undefined || path !== undefined)) {
10
+ throw new UsageError("Use either --template-file or --folder with --path, not both.", "conflicting_input_sources");
11
+ }
12
+ if (typeof file === "string")
13
+ return { kind: "file", filePath: file, };
14
+ if (typeof folder === "string" || typeof path === "string") {
15
+ if (typeof folder !== "string" || typeof path !== "string") {
16
+ throw new UsageError("A template in a managed folder needs both --folder FOLDER_ID and --path PATH.", "missing_required_flag");
17
+ }
18
+ return { kind: "folder", folderId: folder, path, };
19
+ }
20
+ return { kind: "default", };
21
+ }
22
+ /** `--poll-interval` / `--timeout` for commands that wait on a DSS task. */
23
+ export function taskWaitOptions(flags) {
24
+ return {
25
+ pollIntervalMs: num(flags["poll-interval"], "--poll-interval"),
26
+ timeoutMs: num(flags["timeout"], "--timeout"),
27
+ };
28
+ }
29
+ /**
30
+ * Shared `generate-documentation` flow: return the started task; with
31
+ * --wait, its final state; with --output PATH, wait and download the docx
32
+ * named by the result's `exportId`. A failed or timed-out generation carries
33
+ * no exportId, so its state is returned instead.
34
+ */
35
+ export async function runDocumentationCommand(client, flags, task, download) {
36
+ const output = flags["output"];
37
+ if (flags["wait"] !== true && typeof output !== "string")
38
+ return task;
39
+ const waited = await client.futures.waitTask(task, taskWaitOptions(flags));
40
+ if (typeof output !== "string")
41
+ return waited;
42
+ const result = waited.result;
43
+ const exportId = result && typeof result === "object" && "exportId" in result
44
+ ? result.exportId
45
+ : undefined;
46
+ if (typeof exportId !== "string")
47
+ return waited;
48
+ return {
49
+ path: output,
50
+ bytes: await writeResponseToFile(output, await download(exportId)),
51
+ exportId,
52
+ };
53
+ }
@@ -1,6 +1,7 @@
1
1
  import type { DataikuClient } from "../../client.js";
2
2
  import type { FlowZoneItemInput } from "../../resources/flow-zones.js";
3
3
  import type { FlowZone, FlowZoneObjectType, FlowZonePosition } from "../../schemas.js";
4
+ import type { NormalizedFlowMap } from "../../utils/flow-map.js";
4
5
  export declare function flowZoneId(value: string): string;
5
6
  export declare function flowZoneName(value: string | boolean | undefined): string;
6
7
  export declare function flowZoneColor(value: string | boolean | undefined): string | undefined;
@@ -18,6 +19,8 @@ export interface FlowZoneOrganizeZonePlan {
18
19
  color?: string;
19
20
  position?: FlowZonePosition;
20
21
  items: FlowZoneItemInput[];
22
+ /** Recipe/output unit members added by {@link applyFlowZoneUnits}; also present in `items`. */
23
+ impliedItems?: FlowZoneItemInput[];
21
24
  }
22
25
  export interface FlowZoneOrganizePlan {
23
26
  topologyFingerprint?: string;
@@ -60,7 +63,25 @@ export declare function flowZoneExplicitItems(zone: FlowZone): FlowZoneItemInput
60
63
  export declare function flowZonePlanFromZones(zones: FlowZone[], topologyFingerprint: string): FlowZoneOrganizePlan;
61
64
  export declare function flowZoneMoveDelta(existing: FlowZone | undefined, plannedItems: FlowZoneItemInput[]): FlowZoneItemInput[];
62
65
  export declare function flowZonePruneItems(existing: FlowZone | undefined, plannedItemKeys: Set<string>): FlowZoneItemInput[];
66
+ /**
67
+ * The position an existing zone must move to, if the plan changes it. DSS
68
+ * honors a zone position only on creation, so a move means recreating the zone.
69
+ */
70
+ export declare function flowZoneRepositionTarget(plan: FlowZoneOrganizeZonePlan, existing: FlowZone): FlowZonePosition | undefined;
63
71
  export declare function flowZoneOrganizeStep(plan: FlowZoneOrganizeZonePlan, existing: FlowZone | undefined, sync: boolean, plannedItemKeys: Set<string>): Record<string, unknown>;
72
+ /**
73
+ * Enforce the DSS recipe/output zone invariant on a plan. Rejects plans that
74
+ * place members of one unit in different zones (they would never converge),
75
+ * and adds the unlisted members of each planned unit to that zone as
76
+ * `impliedItems`, so moves, `--sync` pruning, and reruns all agree with what
77
+ * DSS actually does.
78
+ */
79
+ export declare function applyFlowZoneUnits(plan: FlowZoneOrganizePlan, graph: NormalizedFlowMap, zones: FlowZone[], projectKey: string | undefined): FlowZoneOrganizePlan;
80
+ /**
81
+ * Default-zone objects an organization plan has to place: recipes (their
82
+ * outputs follow) and objects no recipe produces, such as uploaded sources.
83
+ */
84
+ export declare function flowZoneUnassignedItems(graph: NormalizedFlowMap, zones: FlowZone[]): FlowZoneItemInput[];
64
85
  export declare function flowZoneValidationBucket(index: FlowZoneOrganizeValidationIndex, objectType: FlowZoneObjectType): Set<string>;
65
86
  export declare function flowZoneValidationIndex(client: DataikuClient, projectKey: string | undefined): Promise<FlowZoneOrganizeValidationIndex>;
66
87
  export declare function validateFlowZoneOrganizeObjects(client: DataikuClient, plan: FlowZoneOrganizePlan, projectKey: string | undefined): Promise<FlowZoneOrganizeValidationResult>;