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.
- package/README.md +14 -6
- package/bin/bun-version.js +14 -0
- package/bin/dss.js +11 -15
- package/dist/build-metadata.json +1 -1
- package/dist/packages/types/src/index.d.ts +114 -5
- package/dist/packages/types/src/index.js +75 -2
- package/dist/src/cli/coerce.d.ts +2 -0
- package/dist/src/cli/coerce.js +20 -16
- package/dist/src/cli/command-syntax.json +3369 -144
- package/dist/src/cli/commands/analysis.js +19 -1
- package/dist/src/cli/commands/bundle.js +22 -0
- package/dist/src/cli/commands/connection.js +26 -2
- package/dist/src/cli/commands/data-quality.js +33 -1
- package/dist/src/cli/commands/dataset.js +76 -9
- package/dist/src/cli/commands/discussion.js +15 -0
- package/dist/src/cli/commands/doctor.js +1 -1
- package/dist/src/cli/commands/flow-zone.js +241 -46
- package/dist/src/cli/commands/flow.d.ts +5 -0
- package/dist/src/cli/commands/flow.js +57 -0
- package/dist/src/cli/commands/future.js +8 -0
- package/dist/src/cli/commands/index.js +6 -0
- package/dist/src/cli/commands/job.js +44 -6
- package/dist/src/cli/commands/metrics.js +21 -1
- package/dist/src/cli/commands/ml-task.d.ts +5 -0
- package/dist/src/cli/commands/ml-task.js +86 -16
- package/dist/src/cli/commands/mlflow.d.ts +11 -0
- package/dist/src/cli/commands/mlflow.js +121 -0
- package/dist/src/cli/commands/plugin.js +5 -11
- package/dist/src/cli/commands/project-deployer.js +70 -0
- package/dist/src/cli/commands/project-library.js +2 -5
- package/dist/src/cli/commands/project.js +8 -0
- package/dist/src/cli/commands/recipe.d.ts +13 -0
- package/dist/src/cli/commands/recipe.js +130 -7
- package/dist/src/cli/commands/saved-model.d.ts +1 -1
- package/dist/src/cli/commands/saved-model.js +9 -76
- package/dist/src/cli/commands/streaming-endpoint.js +30 -1
- package/dist/src/cli/commands/webapp.js +8 -0
- package/dist/src/cli/commands/wiki.js +78 -0
- package/dist/src/cli/commands/workspace.js +8 -0
- package/dist/src/cli/contract.d.ts +16 -15
- package/dist/src/cli/contract.js +150 -3407
- package/dist/src/cli/doctor.d.ts +13 -0
- package/dist/src/cli/doctor.js +43 -1
- package/dist/src/cli/flags.d.ts +14 -1
- package/dist/src/cli/flags.js +106 -8
- package/dist/src/cli/helpers/app-successor.js +1 -2
- package/dist/src/cli/helpers/dataset.d.ts +12 -0
- package/dist/src/cli/helpers/dataset.js +36 -0
- package/dist/src/cli/helpers/documentation.d.ts +21 -0
- package/dist/src/cli/helpers/documentation.js +53 -0
- package/dist/src/cli/helpers/flow-zone.d.ts +21 -0
- package/dist/src/cli/helpers/flow-zone.js +144 -4
- package/dist/src/cli/helpers/trained-model.d.ts +26 -0
- package/dist/src/cli/helpers/trained-model.js +144 -0
- package/dist/src/cli/list-output.d.ts +7 -0
- package/dist/src/cli/list-output.js +77 -0
- package/dist/src/cli/list-shapes.d.ts +21 -0
- package/dist/src/cli/list-shapes.js +111 -0
- package/dist/src/cli/output-schemas.d.ts +0 -14
- package/dist/src/cli/output-schemas.js +4 -7
- package/dist/src/cli/output.d.ts +0 -1
- package/dist/src/cli/output.js +33 -19
- package/dist/src/cli/plans.d.ts +14 -0
- package/dist/src/cli/plans.js +3740 -0
- package/dist/src/cli/types.d.ts +2 -0
- package/dist/src/cli/usage.d.ts +7 -0
- package/dist/src/cli/usage.js +20 -1
- package/dist/src/cli/version.d.ts +2 -2
- package/dist/src/cli/version.js +2 -2
- package/dist/src/cli.js +137 -115
- package/dist/src/client.d.ts +52 -43
- package/dist/src/client.js +267 -96
- package/dist/src/errors.d.ts +22 -2
- package/dist/src/errors.js +49 -50
- package/dist/src/generated/action-output-schemas.json +345 -89
- package/dist/src/index.d.ts +5 -1
- package/dist/src/index.js +3 -0
- package/dist/src/resources/analyses.d.ts +8 -0
- package/dist/src/resources/analyses.js +13 -1
- package/dist/src/resources/bundles.d.ts +34 -0
- package/dist/src/resources/bundles.js +67 -0
- package/dist/src/resources/connections.d.ts +9 -0
- package/dist/src/resources/connections.js +15 -0
- package/dist/src/resources/data-quality.d.ts +20 -0
- package/dist/src/resources/data-quality.js +30 -0
- package/dist/src/resources/dataset-create.d.ts +38 -0
- package/dist/src/resources/dataset-create.js +135 -0
- package/dist/src/resources/datasets.d.ts +46 -15
- package/dist/src/resources/datasets.js +120 -112
- package/dist/src/resources/discussions.d.ts +5 -0
- package/dist/src/resources/discussions.js +7 -0
- package/dist/src/resources/documentation.d.ts +25 -0
- package/dist/src/resources/documentation.js +16 -0
- package/dist/src/resources/flow-zones.d.ts +29 -3
- package/dist/src/resources/flow-zones.js +53 -3
- package/dist/src/resources/flow.d.ts +48 -0
- package/dist/src/resources/flow.js +65 -0
- package/dist/src/resources/futures.d.ts +23 -0
- package/dist/src/resources/futures.js +32 -0
- package/dist/src/resources/jobs.d.ts +34 -0
- package/dist/src/resources/jobs.js +170 -3
- package/dist/src/resources/metrics.d.ts +10 -0
- package/dist/src/resources/metrics.js +10 -0
- package/dist/src/resources/ml-tasks.d.ts +65 -2
- package/dist/src/resources/ml-tasks.js +102 -28
- package/dist/src/resources/mlflow-extension.d.ts +73 -0
- package/dist/src/resources/mlflow-extension.js +105 -0
- package/dist/src/resources/projects.d.ts +15 -0
- package/dist/src/resources/projects.js +18 -3
- package/dist/src/resources/recipe-create.d.ts +79 -0
- package/dist/src/resources/recipe-create.js +454 -0
- package/dist/src/resources/recipes.d.ts +28 -29
- package/dist/src/resources/recipes.js +201 -267
- package/dist/src/resources/saved-models.d.ts +10 -6
- package/dist/src/resources/saved-models.js +16 -14
- package/dist/src/resources/scenarios.js +8 -14
- package/dist/src/resources/sql.js +52 -13
- package/dist/src/resources/streaming-endpoints.d.ts +12 -0
- package/dist/src/resources/streaming-endpoints.js +15 -0
- package/dist/src/resources/trained-model.d.ts +60 -0
- package/dist/src/resources/trained-model.js +98 -0
- package/dist/src/resources/webapps.d.ts +8 -0
- package/dist/src/resources/webapps.js +10 -0
- package/dist/src/resources/wiki.d.ts +52 -1
- package/dist/src/resources/wiki.js +96 -0
- package/dist/src/resources/workspaces.d.ts +2 -0
- package/dist/src/resources/workspaces.js +4 -0
- package/dist/src/utils/flow-analysis.js +4 -0
- package/dist/src/utils/response-file.js +20 -9
- package/dist/src/utils/secret-sanitize.d.ts +7 -0
- package/dist/src/utils/secret-sanitize.js +46 -0
- package/package.json +25 -26
- package/plugin.json +1 -1
- package/skills/dataiku-dss/SKILL.md +1 -1
- package/skills/dataiku-dss/references/authentication.md +3 -1
- package/skills/dataiku-dss/references/coding.md +1 -0
- package/skills/dataiku-dss/references/discovery.md +4 -6
- package/skills/dataiku-dss/references/flow-maps.md +2 -2
- package/skills/dataiku-dss/references/troubleshooting.md +3 -2
package/dist/src/cli/doctor.d.ts
CHANGED
|
@@ -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;
|
package/dist/src/cli/doctor.js
CHANGED
|
@@ -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 = {
|
|
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;
|
package/dist/src/cli/flags.d.ts
CHANGED
|
@@ -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 {
|
package/dist/src/cli/flags.js
CHANGED
|
@@ -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
|
|
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 ||
|
|
286
|
-
|
|
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
|
|
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>;
|