dataiku-sdk 3.3.0 → 3.4.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 (37) hide show
  1. package/README.md +3 -1
  2. package/dist/build-metadata.json +1 -1
  3. package/dist/src/cli/commands/code.js +1 -1
  4. package/dist/src/cli/commands/dataset.js +1 -1
  5. package/dist/src/cli/commands/job.js +4 -2
  6. package/dist/src/cli/commands/macro.js +2 -2
  7. package/dist/src/cli/commands/project-git.js +1 -1
  8. package/dist/src/cli/commands/scenario.js +1 -1
  9. package/dist/src/cli/contract.js +23 -208
  10. package/dist/src/cli/output-schemas.d.ts +24 -0
  11. package/dist/src/cli/output-schemas.js +233 -0
  12. package/dist/src/client.d.ts +10 -1
  13. package/dist/src/client.js +20 -5
  14. package/dist/src/errors.js +6 -4
  15. package/dist/src/generated/action-output-schemas.json +1735 -0
  16. package/dist/src/resources/datasets.js +37 -4
  17. package/dist/src/resources/flow-zones.d.ts +6 -2
  18. package/dist/src/resources/flow-zones.js +6 -3
  19. package/dist/src/resources/futures.d.ts +2 -0
  20. package/dist/src/resources/futures.js +38 -24
  21. package/dist/src/resources/jobs.js +37 -25
  22. package/dist/src/resources/ml-tasks.js +28 -19
  23. package/dist/src/resources/plugins.d.ts +0 -2
  24. package/dist/src/resources/plugins.js +0 -3
  25. package/dist/src/resources/project-git.d.ts +6 -12
  26. package/dist/src/resources/project-git.js +23 -48
  27. package/dist/src/resources/projects.d.ts +4 -2
  28. package/dist/src/resources/projects.js +33 -33
  29. package/dist/src/utils/git-reference.d.ts +12 -0
  30. package/dist/src/utils/git-reference.js +38 -0
  31. package/package.json +5 -5
  32. package/plugin.json +1 -1
  33. package/skills/dataiku-dss/SKILL.md +4 -2
  34. package/skills/dataiku-dss/references/app-releases.md +2 -3
  35. package/skills/dataiku-dss/references/authentication.md +6 -6
  36. package/skills/dataiku-dss/references/mutations.md +1 -1
  37. package/skills/dataiku-dss/references/troubleshooting.md +2 -2
@@ -73,6 +73,15 @@ export interface DataikuGetOptions {
73
73
  * budget may shorten those limits but never extends them.
74
74
  */
75
75
  timeoutMs?: number;
76
+ /**
77
+ * Issue exactly one transport attempt (no retries). Independent of
78
+ * `timeoutMs`: when both are supplied the total budget above still applies
79
+ * and aborts the attempt; when no budget is supplied the attempt is capped
80
+ * by the client-level `requestTimeoutMs`. Wait loops use this for the one
81
+ * observation whose wait budget is already spent, so it still reaches the
82
+ * server once instead of failing before any transport attempt.
83
+ */
84
+ noRetry?: boolean;
76
85
  }
77
86
  export interface DataikuClientTraceEvent {
78
87
  type: "trace";
@@ -298,7 +307,7 @@ export declare class DataikuClient {
298
307
  /** Send raw file contents through the shared authenticated transport. */
299
308
  postRawBody(path: string, body: string | Uint8Array): Promise<void>;
300
309
  /** Git endpoints require Basic API-key authentication, unlike the bearer API. */
301
- requestGit(method: string, path: string, body?: unknown, deadlineAt?: number): Promise<Response>;
310
+ requestGit(method: string, path: string, body?: unknown, deadlineAt?: number, noRetry?: boolean): Promise<Response>;
302
311
  postStream(path: string, body?: unknown): Promise<Response>;
303
312
  put<T = unknown>(path: string, body: unknown): Promise<T>;
304
313
  del(path: string): Promise<void>;
@@ -78,6 +78,19 @@ function computeBackoffDelayMs(retryNumber) {
78
78
  const cap = Math.min(MAX_BACKOFF_DELAY_MS, BASE_DELAY_MS * 2 ** Math.max(0, retryNumber - 1));
79
79
  return Math.floor(Math.random() * (cap + 1));
80
80
  }
81
+ /** Server-directed waits never bypass the existing automatic backoff cap. */
82
+ function retryAfterDelayMs(value) {
83
+ if (value === null)
84
+ return 0;
85
+ const text = value.trim();
86
+ if (/^\d+$/.test(text))
87
+ return Number(text) * 1_000;
88
+ // Accept HTTP dates, not Date.parse's permissive numeric date shorthand.
89
+ if (!/^[A-Za-z]{3,9},? /.test(text))
90
+ return 0;
91
+ const date = Date.parse(text);
92
+ return Number.isFinite(date) ? Math.max(0, date - Date.now()) : 0;
93
+ }
81
94
  function isTransientError(status, body) {
82
95
  return classifyDataikuError(status, body).category === "transient";
83
96
  }
@@ -455,7 +468,7 @@ export class DataikuClient {
455
468
  /* ---- public: HTTP verbs ---- */
456
469
  async get(path, options) {
457
470
  const deadlineAt = resolveGetDeadlineAt(options);
458
- const res = await this.fetchWithRetry(`${this.baseUrl}${path}`, { method: "GET", headers: this.getHeaders(), }, undefined, deadlineAt);
471
+ const res = await this.fetchWithRetry(`${this.baseUrl}${path}`, { method: "GET", headers: this.getHeaders(), }, options?.noRetry === true ? 1 : undefined, deadlineAt);
459
472
  return this.parseJsonResponse(res, deadlineAt);
460
473
  }
461
474
  /**
@@ -563,7 +576,7 @@ export class DataikuClient {
563
576
  await response.text();
564
577
  }
565
578
  /** Git endpoints require Basic API-key authentication, unlike the bearer API. */
566
- async requestGit(method, path, body, deadlineAt) {
579
+ async requestGit(method, path, body, deadlineAt, noRetry = false) {
567
580
  return this.fetchWithRetry(`${this.baseUrl}${path}`, {
568
581
  method,
569
582
  headers: {
@@ -572,7 +585,7 @@ export class DataikuClient {
572
585
  "Content-Type": "application/json",
573
586
  },
574
587
  body: body === undefined ? undefined : JSON.stringify(body),
575
- }, undefined, deadlineAt);
588
+ }, noRetry ? 1 : undefined, deadlineAt);
576
589
  }
577
590
  async postStream(path, body) {
578
591
  const res = await this.fetchWithRetry(`${this.baseUrl}${path}`, {
@@ -1018,8 +1031,10 @@ export class DataikuClient {
1018
1031
  if (!res.ok) {
1019
1032
  const { text, truncated, } = await this.readBoundedBodyText(res, this.maxResponseBodyBytes, startedAt + attemptTimeoutMs);
1020
1033
  const canRetry = retryEnabled && attempt < maxAttempts && isTransientError(res.status, text);
1021
- if (canRetry) {
1022
- const delayMs = computeBackoffDelayMs(attempt);
1034
+ const serverDelayMs = canRetry ? retryAfterDelayMs(res.headers.get("retry-after")) : 0;
1035
+ // A longer server wait declines automatic retry; never clamp it into an early request.
1036
+ if (canRetry && serverDelayMs <= MAX_BACKOFF_DELAY_MS) {
1037
+ const delayMs = Math.max(computeBackoffDelayMs(attempt), serverDelayMs);
1023
1038
  // Do not start a retry whose backoff cannot fit in the budget.
1024
1039
  if (deadlineAt === undefined || Date.now() + delayMs <= deadlineAt) {
1025
1040
  delaysMs.push(delayMs);
@@ -92,10 +92,12 @@ function firstHtmlTextLine(body) {
92
92
  .replace(/<script\b[^>]*>[\s\S]*?<\/script>/gi, " ")
93
93
  .replace(/<style\b[^>]*>[\s\S]*?<\/style>/gi, " ")
94
94
  .replace(/<[^>]+>/g, "\n"));
95
- return text
96
- .split(/\r?\n/g)
97
- .map((line) => line.trim())
98
- .find((line) => line.length > 0);
95
+ for (const match of text.matchAll(/[^\n]+/g)) {
96
+ const line = match[0].trim();
97
+ if (line.length > 0)
98
+ return line;
99
+ }
100
+ return undefined;
99
101
  }
100
102
  function conciseErrorSummary(text) {
101
103
  const sanitized = stripServerFilesystemPaths(text);