dataiku-sdk 0.10.1 → 0.12.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 (151) hide show
  1. package/LICENSE +21 -0
  2. package/dist/packages/types/src/index.d.ts +19 -2
  3. package/dist/packages/types/src/index.js +13 -1
  4. package/dist/src/cli/coerce.d.ts +36 -0
  5. package/dist/src/cli/coerce.js +239 -0
  6. package/dist/src/cli/commands/analysis.d.ts +2 -0
  7. package/dist/src/cli/commands/analysis.js +66 -0
  8. package/dist/src/cli/commands/api-deployer.d.ts +2 -0
  9. package/dist/src/cli/commands/api-deployer.js +170 -0
  10. package/dist/src/cli/commands/api-service.d.ts +2 -0
  11. package/dist/src/cli/commands/api-service.js +121 -0
  12. package/dist/src/cli/commands/app.d.ts +2 -0
  13. package/dist/src/cli/commands/app.js +78 -0
  14. package/dist/src/cli/commands/bundle.d.ts +2 -0
  15. package/dist/src/cli/commands/bundle.js +107 -0
  16. package/dist/src/cli/commands/business-app.d.ts +2 -0
  17. package/dist/src/cli/commands/business-app.js +76 -0
  18. package/dist/src/cli/commands/code-env.d.ts +2 -0
  19. package/dist/src/cli/commands/code-env.js +255 -0
  20. package/dist/src/cli/commands/code.d.ts +2 -0
  21. package/dist/src/cli/commands/code.js +63 -0
  22. package/dist/src/cli/commands/connection.d.ts +2 -0
  23. package/dist/src/cli/commands/connection.js +54 -0
  24. package/dist/src/cli/commands/continuous-activity.d.ts +2 -0
  25. package/dist/src/cli/commands/continuous-activity.js +38 -0
  26. package/dist/src/cli/commands/dashboard.d.ts +2 -0
  27. package/dist/src/cli/commands/dashboard.js +99 -0
  28. package/dist/src/cli/commands/data-quality.d.ts +2 -0
  29. package/dist/src/cli/commands/data-quality.js +235 -0
  30. package/dist/src/cli/commands/dataset.d.ts +2 -0
  31. package/dist/src/cli/commands/dataset.js +288 -0
  32. package/dist/src/cli/commands/discussion.d.ts +2 -0
  33. package/dist/src/cli/commands/discussion.js +47 -0
  34. package/dist/src/cli/commands/doctor.d.ts +2 -0
  35. package/dist/src/cli/commands/doctor.js +9 -0
  36. package/dist/src/cli/commands/flow-zone.d.ts +2 -0
  37. package/dist/src/cli/commands/flow-zone.js +282 -0
  38. package/dist/src/cli/commands/folder.d.ts +2 -0
  39. package/dist/src/cli/commands/folder.js +202 -0
  40. package/dist/src/cli/commands/future.d.ts +2 -0
  41. package/dist/src/cli/commands/future.js +57 -0
  42. package/dist/src/cli/commands/index.d.ts +2 -0
  43. package/dist/src/cli/commands/index.js +78 -0
  44. package/dist/src/cli/commands/insight.d.ts +2 -0
  45. package/dist/src/cli/commands/insight.js +156 -0
  46. package/dist/src/cli/commands/job.d.ts +2 -0
  47. package/dist/src/cli/commands/job.js +406 -0
  48. package/dist/src/cli/commands/meaning.d.ts +2 -0
  49. package/dist/src/cli/commands/meaning.js +115 -0
  50. package/dist/src/cli/commands/metrics.d.ts +2 -0
  51. package/dist/src/cli/commands/metrics.js +39 -0
  52. package/dist/src/cli/commands/ml-task.d.ts +2 -0
  53. package/dist/src/cli/commands/ml-task.js +171 -0
  54. package/dist/src/cli/commands/model-evaluation-store.d.ts +2 -0
  55. package/dist/src/cli/commands/model-evaluation-store.js +83 -0
  56. package/dist/src/cli/commands/notebook.d.ts +2 -0
  57. package/dist/src/cli/commands/notebook.js +242 -0
  58. package/dist/src/cli/commands/project-deployer.d.ts +2 -0
  59. package/dist/src/cli/commands/project-deployer.js +118 -0
  60. package/dist/src/cli/commands/project-library.d.ts +2 -0
  61. package/dist/src/cli/commands/project-library.js +197 -0
  62. package/dist/src/cli/commands/project.d.ts +2 -0
  63. package/dist/src/cli/commands/project.js +133 -0
  64. package/dist/src/cli/commands/recipe.d.ts +2 -0
  65. package/dist/src/cli/commands/recipe.js +659 -0
  66. package/dist/src/cli/commands/saved-model.d.ts +2 -0
  67. package/dist/src/cli/commands/saved-model.js +85 -0
  68. package/dist/src/cli/commands/scenario.d.ts +2 -0
  69. package/dist/src/cli/commands/scenario.js +190 -0
  70. package/dist/src/cli/commands/sql.d.ts +2 -0
  71. package/dist/src/cli/commands/sql.js +109 -0
  72. package/dist/src/cli/commands/statistics.d.ts +2 -0
  73. package/dist/src/cli/commands/statistics.js +165 -0
  74. package/dist/src/cli/commands/streaming-endpoint.d.ts +2 -0
  75. package/dist/src/cli/commands/streaming-endpoint.js +50 -0
  76. package/dist/src/cli/commands/variable.d.ts +2 -0
  77. package/dist/src/cli/commands/variable.js +49 -0
  78. package/dist/src/cli/commands/webapp.d.ts +2 -0
  79. package/dist/src/cli/commands/webapp.js +67 -0
  80. package/dist/src/cli/commands/wiki.d.ts +2 -0
  81. package/dist/src/cli/commands/wiki.js +123 -0
  82. package/dist/src/cli/commands/workspace.d.ts +2 -0
  83. package/dist/src/cli/commands/workspace.js +68 -0
  84. package/dist/src/cli/contract.d.ts +104 -0
  85. package/dist/src/cli/contract.js +2041 -0
  86. package/dist/src/cli/doctor.d.ts +104 -0
  87. package/dist/src/cli/doctor.js +356 -0
  88. package/dist/src/cli/env.d.ts +2 -0
  89. package/dist/src/cli/env.js +37 -0
  90. package/dist/src/cli/flags.d.ts +16 -0
  91. package/dist/src/cli/flags.js +272 -0
  92. package/dist/src/cli/helpers/cleanup.d.ts +3 -0
  93. package/dist/src/cli/helpers/cleanup.js +204 -0
  94. package/dist/src/cli/helpers/dataset.d.ts +2 -0
  95. package/dist/src/cli/helpers/dataset.js +17 -0
  96. package/dist/src/cli/helpers/flow-zone.d.ts +69 -0
  97. package/dist/src/cli/helpers/flow-zone.js +420 -0
  98. package/dist/src/cli/helpers/recipe.d.ts +11 -0
  99. package/dist/src/cli/helpers/recipe.js +83 -0
  100. package/dist/src/cli/output.d.ts +38 -0
  101. package/dist/src/cli/output.js +159 -0
  102. package/dist/src/cli/runtime.d.ts +15 -0
  103. package/dist/src/cli/runtime.js +59 -0
  104. package/dist/src/cli/types.d.ts +25 -0
  105. package/dist/src/cli/types.js +1 -0
  106. package/dist/src/cli/usage.d.ts +16 -0
  107. package/dist/src/cli/usage.js +84 -0
  108. package/dist/src/cli/version.d.ts +14 -0
  109. package/dist/src/cli/version.js +63 -0
  110. package/dist/src/cli.js +671 -8254
  111. package/dist/src/client.d.ts +13 -1
  112. package/dist/src/client.js +34 -13
  113. package/dist/src/errors.d.ts +6 -0
  114. package/dist/src/errors.js +102 -4
  115. package/dist/src/index.d.ts +7 -3
  116. package/dist/src/index.js +6 -2
  117. package/dist/src/resources/analyses.d.ts +34 -0
  118. package/dist/src/resources/analyses.js +31 -0
  119. package/dist/src/resources/api-services.d.ts +2 -0
  120. package/dist/src/resources/api-services.js +10 -0
  121. package/dist/src/resources/applications.d.ts +1 -1
  122. package/dist/src/resources/applications.js +27 -1
  123. package/dist/src/resources/continuous-activities.js +1 -0
  124. package/dist/src/resources/data-quality.js +5 -3
  125. package/dist/src/resources/datasets.d.ts +3 -0
  126. package/dist/src/resources/datasets.js +10 -5
  127. package/dist/src/resources/flow-zones.d.ts +2 -2
  128. package/dist/src/resources/flow-zones.js +4 -1
  129. package/dist/src/resources/meanings.d.ts +2 -0
  130. package/dist/src/resources/meanings.js +4 -0
  131. package/dist/src/resources/ml-tasks.d.ts +91 -0
  132. package/dist/src/resources/ml-tasks.js +130 -0
  133. package/dist/src/resources/model-evaluation-stores.d.ts +41 -0
  134. package/dist/src/resources/model-evaluation-stores.js +36 -0
  135. package/dist/src/resources/notebooks.d.ts +5 -7
  136. package/dist/src/resources/notebooks.js +10 -7
  137. package/dist/src/resources/projects.d.ts +1 -1
  138. package/dist/src/resources/projects.js +2 -2
  139. package/dist/src/resources/recipes.d.ts +3 -3
  140. package/dist/src/resources/recipes.js +198 -38
  141. package/dist/src/resources/saved-models.d.ts +41 -0
  142. package/dist/src/resources/saved-models.js +40 -0
  143. package/dist/src/resources/scenarios.js +67 -26
  144. package/dist/src/resources/statistics.js +9 -0
  145. package/dist/src/schemas.d.ts +2 -2
  146. package/dist/src/schemas.js +1 -1
  147. package/dist/src/skill.js +2 -2
  148. package/dist/src/utils/sanitize.js +2 -1
  149. package/package.json +1 -1
  150. package/packages/types/dist/index.d.ts +19 -2
  151. package/packages/types/dist/index.js +13 -1
@@ -22,6 +22,67 @@ function asRecord(value) {
22
22
  return undefined;
23
23
  return value;
24
24
  }
25
+ function parseRecipePayload(payload) {
26
+ if (!payload)
27
+ return {};
28
+ const parsed = JSON.parse(payload);
29
+ return asRecord(parsed) ?? {};
30
+ }
31
+ function parseJoinKeyPairs(values, optionName = "joinOn") {
32
+ const pairs = [];
33
+ for (const raw of values) {
34
+ const token = raw.trim();
35
+ if (!token)
36
+ continue;
37
+ const eq = token.indexOf("=");
38
+ if (eq === -1) {
39
+ pairs.push({ left: token, right: token, });
40
+ continue;
41
+ }
42
+ const left = token.slice(0, eq).trim();
43
+ const right = token.slice(eq + 1).trim();
44
+ if (!left || !right)
45
+ throw new Error(`${optionName} values must use COL or LEFT=RIGHT.`);
46
+ pairs.push({ left, right, });
47
+ }
48
+ return pairs;
49
+ }
50
+ function normalizeFuzzyDistance(value) {
51
+ const normalized = typeof value === "string" && value.trim().length > 0
52
+ ? value.trim().toUpperCase()
53
+ : "DAMERAU_LEVENSHTEIN";
54
+ if (normalized === "DAMERAU_LEVENSHTEIN")
55
+ return "LEVENSHTEIN";
56
+ if (normalized === "HAMMING" || normalized === "JACCARD" || normalized === "COSINE"
57
+ || normalized === "EUCLIDEAN") {
58
+ return normalized;
59
+ }
60
+ throw new Error("fuzzyDistance must be one of DAMERAU_LEVENSHTEIN, HAMMING, JACCARD, COSINE, or EUCLIDEAN.");
61
+ }
62
+ function normalizeJoinType(value) {
63
+ const normalized = typeof value === "string" && value.trim().length > 0
64
+ ? value.trim().toUpperCase()
65
+ : "LEFT";
66
+ if (normalized === "LEFT" || normalized === "INNER" || normalized === "RIGHT"
67
+ || normalized === "FULL") {
68
+ return normalized;
69
+ }
70
+ throw new Error("joinType must be one of LEFT, INNER, RIGHT, or FULL.");
71
+ }
72
+ function recipeVirtualInputs(payload, inputCount) {
73
+ const current = Array.isArray(payload.virtualInputs) ? payload.virtualInputs : [];
74
+ const virtualInputs = [];
75
+ for (let i = 0; i < inputCount; i++) {
76
+ virtualInputs.push({
77
+ preFilter: {},
78
+ outputColumnsSelectionMode: "AUTO_NON_CONFLICTING",
79
+ computedColumns: [],
80
+ ...asRecord(current[i]),
81
+ index: i,
82
+ });
83
+ }
84
+ return virtualInputs;
85
+ }
25
86
  const RECIPE_DEFINITION_FIELDS = new Set(["params", "inputs", "outputs", "scriptSettings",]);
26
87
  function rootRecipeDefinitionFields(data) {
27
88
  return Object.keys(data).filter((key) => RECIPE_DEFINITION_FIELDS.has(key));
@@ -147,6 +208,20 @@ function rewriteSqlTableReferences(payload, rewrites) {
147
208
  }
148
209
  return next;
149
210
  }
211
+ function rewritePayloadText(payload, rewrites) {
212
+ const entries = Object
213
+ .entries(rewrites)
214
+ .filter(([from,]) => from.length > 0)
215
+ .sort(([left,], [right,]) => right.length - left.length);
216
+ if (entries.length === 0)
217
+ return payload;
218
+ const replacements = new Map(entries);
219
+ const alternatives = entries
220
+ .map(([from,]) => escapedRegExp(from))
221
+ .join("|");
222
+ const pattern = new RegExp(String.raw `(?<![A-Za-z0-9_$])(${alternatives})(?![A-Za-z0-9_$])`, "g");
223
+ return payload.replace(pattern, (match) => replacements.get(match) ?? match);
224
+ }
150
225
  function rewritePayload(payload, rewrites, payloadTextRewrites = {}, recipeType) {
151
226
  if (payload === undefined
152
227
  || (Object.keys(rewrites).length === 0 && Object.keys(payloadTextRewrites).length === 0)) {
@@ -162,10 +237,7 @@ function rewritePayload(payload, rewrites, payloadTextRewrites = {}, recipeType)
162
237
  if (isSqlRecipeType(recipeType)) {
163
238
  next = rewriteSqlTableReferences(next, rewrites);
164
239
  }
165
- for (const [from, to,] of Object.entries(payloadTextRewrites)) {
166
- if (from.length > 0)
167
- next = next.split(from).join(to);
168
- }
240
+ next = rewritePayloadText(next, payloadTextRewrites);
169
241
  return next;
170
242
  }
171
243
  function cloneRecipeDefinition(recipe, targetName, projectKey, rewrites) {
@@ -456,17 +528,37 @@ export class RecipesResource extends BaseResource {
456
528
  if (!type || !name || !inputs || !outputs) {
457
529
  throw new Error("type and (inputDatasets + outputDataset/outputFolder) or (name + inputs + outputs) are required for create.");
458
530
  }
531
+ const joinCols = typeof opts.joinOn === "string" ? [opts.joinOn,] : asStringArray(opts.joinOn);
532
+ const joinKeys = type === "join" && joinCols?.length
533
+ ? parseJoinKeyPairs(joinCols)
534
+ : undefined;
535
+ const fuzzyOn = opts.fuzzyOn ?? (type === "fuzzyjoin" ? opts.joinOn : undefined);
536
+ const fuzzyCols = typeof fuzzyOn === "string" ? [fuzzyOn,] : asStringArray(fuzzyOn);
537
+ const fuzzyKeys = type === "fuzzyjoin" && fuzzyCols?.length
538
+ ? parseJoinKeyPairs(fuzzyCols, "fuzzyOn")
539
+ : undefined;
540
+ const normalizedJoinType = joinKeys?.length || fuzzyKeys?.length
541
+ ? normalizeJoinType(rawJoinType)
542
+ : undefined;
543
+ const fuzzyDistance = fuzzyKeys?.length ? normalizeFuzzyDistance(opts.fuzzyDistance) : undefined;
544
+ const fuzzyThreshold = opts.fuzzyThreshold ?? 1;
545
+ if (!Number.isFinite(fuzzyThreshold)) {
546
+ throw new Error("fuzzyThreshold must be a finite number.");
547
+ }
459
548
  const recipePrototype = {
460
549
  type,
461
550
  name,
462
551
  projectKey: pk,
463
- inputs,
552
+ ...(type === "fuzzyjoin" ? {} : { inputs, }),
464
553
  outputs,
465
554
  };
466
555
  const creationSettings = {};
467
556
  if (payload !== undefined) {
468
557
  creationSettings.script = payload;
469
558
  }
559
+ if (type === "fuzzyjoin") {
560
+ creationSettings.virtualInputs = recipeInputItems({ inputs, }).map((item) => item.ref);
561
+ }
470
562
  const createRecipe = () => this.client.post(`/public/api/projects/${enc}/recipes/`, {
471
563
  recipePrototype,
472
564
  creationSettings,
@@ -553,39 +645,62 @@ export class RecipesResource extends BaseResource {
553
645
  await provisionOutputDatasets();
554
646
  await createRecipe();
555
647
  }
648
+ // For sync recipes (a 1:1 copy) DSS does not propagate schema on build, so a
649
+ // schemaless dataset output silently builds to an empty dataset. Copy the
650
+ // single input's schema onto any schemaless dataset output so the build
651
+ // materializes rows (mirrors the DSS UI, which sets the sync output schema).
652
+ let syncOutputSchemaPropagated;
653
+ if (type.toLowerCase() === "sync" && !outputFolder) {
654
+ const inputRefs = recipeInputItems({ inputs, }).map((item) => item.ref);
655
+ const outputDatasetRefs = recipeOutputItems({ outputs, })
656
+ .filter((item) => item.type !== "MANAGED_FOLDER")
657
+ .map((item) => item.ref);
658
+ if (inputRefs.length === 1 && outputDatasetRefs.length > 0) {
659
+ const inputSchema = await this.client.datasets
660
+ .schema(inputRefs[0], pk)
661
+ .catch(() => undefined);
662
+ const inputColumns = inputSchema?.columns;
663
+ if (inputColumns && inputColumns.length > 0) {
664
+ const propagated = [];
665
+ for (const ref of outputDatasetRefs) {
666
+ const current = await this.client.datasets
667
+ .schema(ref, pk)
668
+ .catch(() => undefined);
669
+ if (current && current.columns.length === 0) {
670
+ await this.client.datasets.updateSchema(ref, inputColumns, pk);
671
+ propagated.push(ref);
672
+ }
673
+ }
674
+ if (propagated.length > 0)
675
+ syncOutputSchemaPropagated = propagated;
676
+ }
677
+ }
678
+ }
556
679
  // For join recipes: configure join conditions after creation
557
680
  let joinConfigured = false;
558
- const joinCols = typeof opts.joinOn === "string" ? [opts.joinOn,] : asStringArray(opts.joinOn);
559
- const joinType = asString(rawJoinType) ?? "LEFT";
560
- if (type === "join" && joinCols?.length) {
681
+ if (type === "join" && joinKeys?.length) {
561
682
  const rnEnc = encodeURIComponent(name);
562
683
  const full = await this.client.get(`/public/api/projects/${enc}/recipes/${rnEnc}`);
563
- // DSS returns empty payload for fresh join recipes — construct from scratch
564
- const inputCount = inputDatasets?.length
565
- ?? inputs?.main?.items?.length
566
- ?? 2;
567
- const virtualInputs = [{ index: 0, preFilter: {}, },];
568
- for (let i = 1; i < inputCount; i++) {
569
- virtualInputs.push({
570
- index: i,
571
- on: joinCols.map((col) => ({
572
- column: col,
573
- type: "string",
574
- related: col,
575
- relatedType: "string",
576
- maxMatches: 1,
684
+ const joinPayload = parseRecipePayload(full.payload);
685
+ const inputCount = recipeInputItems({ inputs, }).length || inputDatasets?.length || 2;
686
+ const joinType = normalizedJoinType ?? "LEFT";
687
+ joinPayload.virtualInputs = recipeVirtualInputs(joinPayload, inputCount);
688
+ joinPayload.joins = Array.from({ length: Math.max(0, inputCount - 1), }, (_, index) => {
689
+ const table2 = index + 1;
690
+ return {
691
+ table1: 0,
692
+ table2,
693
+ conditionsMode: "AND",
694
+ type: joinType,
695
+ outerJoinOnTheLeft: joinType === "LEFT",
696
+ on: joinKeys.map((key) => ({
697
+ column1: { name: key.left, table: 0, },
698
+ column2: { name: key.right, table: table2, },
699
+ type: "EQ",
577
700
  })),
578
- joinType,
579
- preFilter: {},
580
- });
581
- }
582
- const joinPayload = {
583
- virtualInputs,
584
- computedColumns: [],
585
- postFilter: {},
586
- };
587
- // Ensure inputs/outputs are set — DSS may not persist them from the POST for join recipes
588
- const updatedFull = {
701
+ };
702
+ });
703
+ await this.client.put(`/public/api/projects/${enc}/recipes/${rnEnc}`, {
589
704
  ...full,
590
705
  recipe: {
591
706
  ...full.recipe,
@@ -593,8 +708,52 @@ export class RecipesResource extends BaseResource {
593
708
  outputs,
594
709
  },
595
710
  payload: JSON.stringify(joinPayload),
596
- };
597
- await this.client.put(`/public/api/projects/${enc}/recipes/${rnEnc}`, updatedFull);
711
+ });
712
+ joinConfigured = true;
713
+ }
714
+ if (type === "fuzzyjoin" && fuzzyKeys?.length) {
715
+ const rnEnc = encodeURIComponent(name);
716
+ const full = await this.client.get(`/public/api/projects/${enc}/recipes/${rnEnc}`);
717
+ const fuzzyPayload = parseRecipePayload(full.payload);
718
+ const inputCount = recipeInputItems({ inputs, }).length || inputDatasets?.length || 2;
719
+ const joinType = normalizedJoinType ?? "LEFT";
720
+ fuzzyPayload.virtualInputs = recipeVirtualInputs(fuzzyPayload, inputCount);
721
+ fuzzyPayload.joins = Array.from({ length: Math.max(0, inputCount - 1), }, (_, index) => {
722
+ const table2 = index + 1;
723
+ return {
724
+ table1: 0,
725
+ table2,
726
+ conditionsMode: "AND",
727
+ type: joinType,
728
+ on: fuzzyKeys.map((key) => ({
729
+ column1: { name: key.left, table: 0, },
730
+ column2: { name: key.right, table: table2, },
731
+ type: "EQ",
732
+ fuzzyMatchDesc: {
733
+ distanceType: fuzzyDistance ?? "LEVENSHTEIN",
734
+ threshold: fuzzyThreshold,
735
+ },
736
+ ...(opts.fuzzyNormalize === true
737
+ ? {
738
+ normaliseDesc: {
739
+ caseInsensitive: true,
740
+ normaliseText: true,
741
+ unicodeCasting: true,
742
+ },
743
+ }
744
+ : {}),
745
+ })),
746
+ };
747
+ });
748
+ await this.client.put(`/public/api/projects/${enc}/recipes/${rnEnc}`, {
749
+ ...full,
750
+ recipe: {
751
+ ...full.recipe,
752
+ inputs,
753
+ outputs,
754
+ },
755
+ payload: JSON.stringify(fuzzyPayload),
756
+ });
598
757
  joinConfigured = true;
599
758
  }
600
759
  let temporaryOutputDatasetDeleted;
@@ -627,6 +786,7 @@ export class RecipesResource extends BaseResource {
627
786
  createdDatasets,
628
787
  joinConfigured,
629
788
  outputProvisioningFallbackUsed: usedOutputProvisioningFallback,
789
+ ...(syncOutputSchemaPropagated ? { syncOutputSchemaPropagated, } : {}),
630
790
  ...(outputFolder ? { outputFolder, } : {}),
631
791
  ...(temporaryOutputDataset ? { temporaryOutputDataset, } : {}),
632
792
  ...(temporaryOutputDatasetDeleted !== undefined ? { temporaryOutputDatasetDeleted, } : {}),
@@ -719,10 +879,10 @@ export class RecipesResource extends BaseResource {
719
879
  };
720
880
  }
721
881
  /**
722
- * Download a recipe code payload to a local file.
882
+ * Download a recipe code payload to a local file.
723
883
 
724
- * Returns the path to the written file.
725
- */
884
+ * Returns the path to the written file.
885
+ */
726
886
  async downloadCode(recipeName, opts) {
727
887
  const result = await this.get(recipeName, {
728
888
  includePayload: true,
@@ -0,0 +1,41 @@
1
+ import { BaseResource } from "./base.js";
2
+ export interface SavedModelListItem extends Record<string, unknown> {
3
+ id?: string;
4
+ name?: string;
5
+ projectKey?: string;
6
+ activeVersion?: string;
7
+ }
8
+ export interface SavedModel extends Record<string, unknown> {
9
+ id?: string;
10
+ name?: string;
11
+ projectKey?: string;
12
+ activeVersion?: string;
13
+ }
14
+ export interface SavedModelVersionListItem extends Record<string, unknown> {
15
+ id?: string;
16
+ active?: boolean;
17
+ createdOn?: number;
18
+ }
19
+ export interface SavedModelVersionDetails extends Record<string, unknown> {
20
+ id?: string;
21
+ algorithm?: string;
22
+ predictionType?: string;
23
+ }
24
+ export interface SavedModelActionResult extends Record<string, unknown> {
25
+ message?: string;
26
+ }
27
+ export declare class SavedModelsResource extends BaseResource {
28
+ /** List saved models in a project. */
29
+ list(projectKey?: string): Promise<SavedModelListItem[]>;
30
+ /** Get saved-model settings and metadata. */
31
+ get(savedModelId: string, projectKey?: string): Promise<SavedModel>;
32
+ /** List all versions of a saved model. */
33
+ listVersions(savedModelId: string, projectKey?: string): Promise<SavedModelVersionListItem[]>;
34
+ /** Get full details for one saved-model version. */
35
+ versionDetails(savedModelId: string, versionId: string, projectKey?: string): Promise<SavedModelVersionDetails>;
36
+ /** Make one saved-model version active. */
37
+ setActiveVersion(savedModelId: string, versionId: string, projectKey?: string): Promise<SavedModelActionResult | undefined>;
38
+ /** Delete a saved model and all of its versions. */
39
+ delete(savedModelId: string, projectKey?: string): Promise<void>;
40
+ private savedModelPath;
41
+ }
@@ -0,0 +1,40 @@
1
+ import { UsageError, } from "../cli/usage.js";
2
+ import { BaseResource, } from "./base.js";
3
+ function requireNonEmpty(value, name) {
4
+ if (typeof value !== "string" || value.trim().length === 0) {
5
+ throw new UsageError(`${name} must be a non-empty string.`, "validation_failed");
6
+ }
7
+ return value;
8
+ }
9
+ export class SavedModelsResource extends BaseResource {
10
+ /** List saved models in a project. */
11
+ async list(projectKey) {
12
+ return this.client.get(`/public/api/projects/${this.enc(projectKey)}/savedmodels/`);
13
+ }
14
+ /** Get saved-model settings and metadata. */
15
+ async get(savedModelId, projectKey) {
16
+ return this.client.get(this.savedModelPath(savedModelId, projectKey));
17
+ }
18
+ /** List all versions of a saved model. */
19
+ async listVersions(savedModelId, projectKey) {
20
+ return this.client.get(`${this.savedModelPath(savedModelId, projectKey)}/versions`);
21
+ }
22
+ /** Get full details for one saved-model version. */
23
+ async versionDetails(savedModelId, versionId, projectKey) {
24
+ const version = encodeURIComponent(requireNonEmpty(versionId, "versionId"));
25
+ return this.client.get(`${this.savedModelPath(savedModelId, projectKey)}/versions/${version}/details`);
26
+ }
27
+ /** Make one saved-model version active. */
28
+ async setActiveVersion(savedModelId, versionId, projectKey) {
29
+ const version = encodeURIComponent(requireNonEmpty(versionId, "versionId"));
30
+ return this.client.post(`${this.savedModelPath(savedModelId, projectKey)}/versions/${version}/actions/setActive`, {});
31
+ }
32
+ /** Delete a saved model and all of its versions. */
33
+ async delete(savedModelId, projectKey) {
34
+ await this.client.del(this.savedModelPath(savedModelId, projectKey));
35
+ }
36
+ savedModelPath(savedModelId, projectKey) {
37
+ const id = encodeURIComponent(requireNonEmpty(savedModelId, "savedModelId"));
38
+ return `/public/api/projects/${this.enc(projectKey)}/savedmodels/${id}`;
39
+ }
40
+ }
@@ -291,46 +291,87 @@ export class ScenariosResource extends BaseResource {
291
291
  * Returns `{ success: false, timedOut: true }` on timeout rather than throwing.
292
292
  */
293
293
  async runAndWait(scenarioId, opts) {
294
- const { runId, } = await this.run(scenarioId, opts?.projectKey);
294
+ const pkEnc = this.enc(opts?.projectKey);
295
+ const base = `/public/api/projects/${pkEnc}/scenarios/${encodeURIComponent(scenarioId)}`;
295
296
  const baseIntervalMs = Math.max(1, opts?.pollIntervalMs ?? 2_000);
296
297
  const adaptivePolling = opts?.pollIntervalMs === undefined;
297
298
  const timeout = Math.max(baseIntervalMs, opts?.timeoutMs ?? 120_000);
298
299
  const startedAt = Date.now();
300
+ // POST /run/ returns a TRIGGER run id, which differs from the actual scenario
301
+ // run id; resolve the real run via get-run-for-trigger so a completed scenario
302
+ // is not misreported as a timeout (the trigger id never matches lastRun).
303
+ const trigger = await this.client.post(`${base}/run/`, {});
304
+ const triggerObj = trigger.trigger;
305
+ const triggerId = triggerObj?.id ?? "manual";
306
+ const triggerRunId = String(trigger.runId ?? trigger.id ?? "");
307
+ if (!triggerRunId) {
308
+ throw new DataikuError(500, "Scenario run not started", `Scenario "${scenarioId}" run trigger returned no run id; cannot track the run.`);
309
+ }
310
+ const trigQuery = `triggerId=${encodeURIComponent(triggerId)}&triggerRunId=${encodeURIComponent(triggerRunId)}`;
311
+ let runId = "";
312
+ let outcome = "UNKNOWN";
299
313
  let pollCount = 0;
314
+ let timedOut = false;
300
315
  while (true) {
301
- pollCount += 1;
302
- const st = await this.status(scenarioId, opts?.projectKey);
303
- const elapsedMs = Date.now() - startedAt;
304
- // Scenario finished when it's no longer running and lastRun matches our runId
305
- if (!st.running && st.lastRun?.runId === runId) {
306
- const outcome = st.lastRun?.outcome ?? "UNKNOWN";
307
- return {
308
- scenarioId,
309
- runId,
310
- outcome,
311
- success: outcome === "SUCCESS",
312
- elapsedMs,
313
- pollCount,
314
- };
316
+ if (Date.now() - startedAt >= timeout) {
317
+ outcome = "TIMEOUT";
318
+ timedOut = true;
319
+ break;
315
320
  }
316
- if (elapsedMs >= timeout) {
317
- return {
318
- scenarioId,
319
- runId,
320
- outcome: "TIMEOUT",
321
- success: false,
322
- elapsedMs,
323
- pollCount,
324
- timedOut: true,
325
- };
321
+ pollCount += 1;
322
+ const run = await this.client.get(`${base}/get-run-for-trigger?${trigQuery}`);
323
+ const scenarioRun = run.scenarioRun;
324
+ if (scenarioRun) {
325
+ runId = scenarioRun.runId ?? runId;
326
+ const result = scenarioRun.result;
327
+ const finished = result?.outcome;
328
+ if (finished) {
329
+ outcome = finished;
330
+ break;
331
+ }
326
332
  }
327
333
  const nextDelayMs = computeNextPollDelayMs({
328
334
  pollCount,
329
335
  baseIntervalMs,
330
336
  adaptiveEnabled: adaptivePolling,
331
337
  });
332
- await new Promise((r) => setTimeout(r, Math.min(nextDelayMs, timeout - elapsedMs)));
338
+ const { promise, resolve, } = Promise.withResolvers();
339
+ setTimeout(resolve, Math.min(nextDelayMs, Math.max(1, timeout - (Date.now() - startedAt))));
340
+ await promise;
333
341
  }
342
+ const resolvedRunId = runId || triggerRunId;
343
+ let steps;
344
+ if (!timedOut && runId) {
345
+ try {
346
+ const details = await this.client.get(`${base}/${encodeURIComponent(runId)}/`);
347
+ const stepRuns = details.stepRuns ?? [];
348
+ const mapped = stepRuns.map((entry) => {
349
+ const stepDef = entry.step;
350
+ const stepResult = entry.result;
351
+ return {
352
+ name: stepDef?.name,
353
+ type: stepDef?.type,
354
+ outcome: stepResult?.outcome ?? "UNKNOWN",
355
+ };
356
+ });
357
+ if (mapped.length > 0)
358
+ steps = mapped;
359
+ }
360
+ catch {
361
+ // Best-effort diagnostics: never fail the wait because the run report is unavailable.
362
+ }
363
+ }
364
+ return {
365
+ scenarioId,
366
+ runId: resolvedRunId,
367
+ outcome,
368
+ success: outcome === "SUCCESS",
369
+ elapsedMs: Date.now() - startedAt,
370
+ pollCount,
371
+ ...(triggerRunId !== resolvedRunId ? { triggerRunId, } : {}),
372
+ ...(timedOut ? { timedOut: true, } : {}),
373
+ ...(steps ? { steps, } : {}),
374
+ };
334
375
  }
335
376
  /**
336
377
  * Run a one-off Python script in a throwaway custom-python scenario and return
@@ -1,7 +1,15 @@
1
+ import { UsageError, } from "../cli/usage.js";
1
2
  import { BaseResource, } from "./base.js";
2
3
  function isRecord(value) {
3
4
  return typeof value === "object" && value !== null && !Array.isArray(value);
4
5
  }
6
+ function validateWorksheetCreateRequest(body) {
7
+ const bodyRecord = isRecord(body) ? body : undefined;
8
+ const dataSpec = bodyRecord?.dataSpec;
9
+ if (!isRecord(dataSpec) || !isRecord(dataSpec.datasetSelection)) {
10
+ throw new UsageError("statistics.createWorksheet requires body.dataSpec.datasetSelection.", "validation_failed", "Include dataSpec.datasetSelection in the worksheet definition.", { requiredField: "dataSpec.datasetSelection", });
11
+ }
12
+ }
5
13
  export class StatisticsResource extends BaseResource {
6
14
  /** List statistics worksheets associated with a dataset. */
7
15
  async listWorksheets(datasetName, projectKey) {
@@ -13,6 +21,7 @@ export class StatisticsResource extends BaseResource {
13
21
  }
14
22
  /** Create a statistics worksheet for a dataset. */
15
23
  async createWorksheet(datasetName, body, projectKey) {
24
+ validateWorksheetCreateRequest(body);
16
25
  return this.client.post(this.worksheetsPath(datasetName, projectKey), body);
17
26
  }
18
27
  /** Replace a statistics worksheet definition. */
@@ -3,5 +3,5 @@
3
3
  * The types package (packages/types/) owns the TypeBox schema definitions.
4
4
  * SDK consumers get everything through this re-export.
5
5
  */
6
- export { BuildModeSchema, CodeEnvActionResultSchema, CodeEnvCreateOptionsSchema, CodeEnvDetailsSchema, CodeEnvPackageListSchema, CodeEnvSetPackagesOptionsSchema, CodeEnvSummaryArraySchema, CodeEnvSummarySchema, CodeEnvUpdatePackagesOptionsSchema, CodeEnvUsageArraySchema, CodeEnvWaitOptionsSchema, ConnectionSummarySchema, DashboardDetailsSchema, DashboardSummaryArraySchema, DashboardSummarySchema, DataQualityComputeResultSchema, DataQualityProjectStatusSchema, DataQualityRuleArraySchema, DataQualityRuleResultArraySchema, DataQualityRuleResultSchema, DataQualityRuleSchema, DataQualityRulesSchema, DataQualityStatusByPartitionSchema, DataQualityStatusSchema, DataQualityTimelineEntrySchema, DataQualityTimelineSchema, DatasetCreateOptionsSchema, DatasetDetailsSchema, DatasetSchemaSchema, DatasetSummaryArraySchema, DatasetSummarySchema, FlowMapOptionsSchema, FlowZoneArraySchema, FlowZoneCreateOptionsSchema, FlowZoneItemSchema, FlowZoneObjectTypeSchema, FlowZonePositionSchema, FlowZoneSchema, FlowZoneUpdateOptionsSchema, FolderCreateOptionsSchema, FolderDetailsSchema, FolderItemArraySchema, FolderItemSchema, FolderSummaryArraySchema, FolderSummarySchema, FutureStateSchema, FutureWaitResultSchema, InsightDetailsSchema, InsightSummaryArraySchema, InsightSummarySchema, JobSummaryArraySchema, JobSummarySchema, JobWaitResultSchema, JupyterCellSchema, JupyterNotebookContentSchema, JupyterNotebookSummaryArraySchema, JupyterNotebookSummarySchema, NotebookSessionArraySchema, NotebookSessionSchema, parseSchema, ProjectDetailsSchema, ProjectMetadataSchema, ProjectSummaryArraySchema, ProjectSummarySchema, ProjectVariablesSchema, RecipeCreateOptionsSchema, RecipeCreateResultSchema, RecipeDetailsSchema, RecipeSummaryArraySchema, RecipeSummarySchema, safeParseSchema, ScenarioDetailsSchema, ScenarioStatusSchema, ScenarioSummaryArraySchema, ScenarioSummarySchema, ScenarioWaitResultSchema, SqlNotebookCellSchema, SqlNotebookContentSchema, SqlNotebookSummaryArraySchema, SqlNotebookSummarySchema, SqlQueryResponseSchema, SqlQueryResultSchema, SqlQuerySchemaSchema, WikiArticleDataArraySchema, WikiArticleDataSchema, WikiArticleMetadataSchema, WikiSettingsSchema, WikiTaxonomyNodeSchema, } from "../packages/types/src/index.js";
7
- export type { BuildMode, CodeEnvActionResult, CodeEnvCreateOptions, CodeEnvDetails, CodeEnvPackageList, CodeEnvSetPackagesOptions, CodeEnvSummary, CodeEnvUpdatePackagesOptions, CodeEnvUsage, CodeEnvWaitOptions, ConnectionSummary, DashboardDetails, DashboardSummary, DataQualityComputeResult, DataQualityProjectStatus, DataQualityRule, DataQualityRuleResult, DataQualityRules, DataQualityStatus, DataQualityStatusByPartition, DataQualityTimeline, DataQualityTimelineEntry, DatasetCreateOptions, DatasetDetails, DatasetSchema, DatasetSummary, FlowMapOptions, FlowZone, FlowZoneCreateOptions, FlowZoneItem, FlowZoneObjectType, FlowZonePosition, FlowZoneUpdateOptions, FolderCreateOptions, FolderDetails, FolderItem, FolderSummary, FutureState, FutureWaitResult, InsightDetails, InsightSummary, JobSummary, JobWaitResult, JupyterCell, JupyterNotebookContent, JupyterNotebookSummary, NotebookSession, ProjectDetails, ProjectMetadata, ProjectSummary, ProjectVariables, RecipeCreateOptions, RecipeCreateResult, RecipeDetails, RecipeSummary, SafeParseResult, ScenarioDetails, ScenarioStatus, ScenarioSummary, ScenarioWaitResult, SqlNotebookCell, SqlNotebookContent, SqlNotebookSummary, SqlQueryResponse, SqlQueryResult, SqlQuerySchema, WikiArticleData, WikiArticleMetadata, WikiSettings, WikiTaxonomyNode, } from "../packages/types/src/index.js";
6
+ export { BuildModeSchema, CodeEnvActionResultSchema, CodeEnvCreateOptionsSchema, CodeEnvDetailsSchema, CodeEnvPackageListSchema, CodeEnvSetPackagesOptionsSchema, CodeEnvSummaryArraySchema, CodeEnvSummarySchema, CodeEnvUpdatePackagesOptionsSchema, CodeEnvUsageArraySchema, CodeEnvWaitOptionsSchema, ConnectionSummarySchema, DashboardDetailsSchema, DashboardSummaryArraySchema, DashboardSummarySchema, DataQualityComputeResultSchema, DataQualityProjectStatusSchema, DataQualityRuleArraySchema, DataQualityRuleResultArraySchema, DataQualityRuleResultSchema, DataQualityRuleSchema, DataQualityRulesSchema, DataQualityStatusByPartitionSchema, DataQualityStatusSchema, DataQualityTimelineEntrySchema, DataQualityTimelineSchema, DatasetCreateOptionsSchema, DatasetDetailsSchema, DatasetSchemaSchema, DatasetSummaryArraySchema, DatasetSummarySchema, FlowMapOptionsSchema, FlowZoneArraySchema, FlowZoneCreateOptionsSchema, FlowZoneItemSchema, FlowZoneObjectTypeSchema, FlowZonePositionSchema, FlowZoneSchema, FlowZoneUpdateOptionsSchema, FolderCreateOptionsSchema, FolderDetailsSchema, FolderItemArraySchema, FolderItemSchema, FolderSummaryArraySchema, FolderSummarySchema, FutureStateSchema, FutureWaitResultSchema, InsightDetailsSchema, InsightSummaryArraySchema, InsightSummarySchema, JobSummaryArraySchema, JobSummarySchema, JobWaitResultSchema, JupyterCellSchema, JupyterNotebookContentSchema, JupyterNotebookSummaryArraySchema, JupyterNotebookSummarySchema, NotebookSessionArraySchema, NotebookSessionSchema, parseSchema, ProjectDetailsSchema, ProjectMetadataSchema, ProjectSummaryArraySchema, ProjectSummarySchema, ProjectVariablesSchema, RecipeCreateOptionsSchema, RecipeCreateResultSchema, RecipeDetailsSchema, RecipeSummaryArraySchema, RecipeSummarySchema, safeParseSchema, ScenarioDetailsSchema, ScenarioStatusSchema, ScenarioStepRunSchema, ScenarioSummaryArraySchema, ScenarioSummarySchema, ScenarioWaitResultSchema, SqlNotebookCellSchema, SqlNotebookContentSchema, SqlNotebookSummaryArraySchema, SqlNotebookSummarySchema, SqlQueryResponseSchema, SqlQueryResultSchema, SqlQuerySchemaSchema, WikiArticleDataArraySchema, WikiArticleDataSchema, WikiArticleMetadataSchema, WikiSettingsSchema, WikiTaxonomyNodeSchema, } from "../packages/types/src/index.js";
7
+ export type { BuildMode, CodeEnvActionResult, CodeEnvCreateOptions, CodeEnvDetails, CodeEnvPackageList, CodeEnvSetPackagesOptions, CodeEnvSummary, CodeEnvUpdatePackagesOptions, CodeEnvUsage, CodeEnvWaitOptions, ConnectionSummary, DashboardDetails, DashboardSummary, DataQualityComputeResult, DataQualityProjectStatus, DataQualityRule, DataQualityRuleResult, DataQualityRules, DataQualityStatus, DataQualityStatusByPartition, DataQualityTimeline, DataQualityTimelineEntry, DatasetCreateOptions, DatasetDetails, DatasetSchema, DatasetSummary, FlowMapOptions, FlowZone, FlowZoneCreateOptions, FlowZoneItem, FlowZoneObjectType, FlowZonePosition, FlowZoneUpdateOptions, FolderCreateOptions, FolderDetails, FolderItem, FolderSummary, FutureState, FutureWaitResult, InsightDetails, InsightSummary, JobSummary, JobWaitResult, JupyterCell, JupyterNotebookContent, JupyterNotebookSummary, NotebookSession, ProjectDetails, ProjectMetadata, ProjectSummary, ProjectVariables, RecipeCreateOptions, RecipeCreateResult, RecipeDetails, RecipeSummary, SafeParseResult, ScenarioDetails, ScenarioStatus, ScenarioStepRun, ScenarioSummary, ScenarioWaitResult, SqlNotebookCell, SqlNotebookContent, SqlNotebookSummary, SqlQueryResponse, SqlQueryResult, SqlQuerySchema, WikiArticleData, WikiArticleMetadata, WikiSettings, WikiTaxonomyNode, } from "../packages/types/src/index.js";
@@ -3,4 +3,4 @@
3
3
  * The types package (packages/types/) owns the TypeBox schema definitions.
4
4
  * SDK consumers get everything through this re-export.
5
5
  */
6
- export { BuildModeSchema, CodeEnvActionResultSchema, CodeEnvCreateOptionsSchema, CodeEnvDetailsSchema, CodeEnvPackageListSchema, CodeEnvSetPackagesOptionsSchema, CodeEnvSummaryArraySchema, CodeEnvSummarySchema, CodeEnvUpdatePackagesOptionsSchema, CodeEnvUsageArraySchema, CodeEnvWaitOptionsSchema, ConnectionSummarySchema, DashboardDetailsSchema, DashboardSummaryArraySchema, DashboardSummarySchema, DataQualityComputeResultSchema, DataQualityProjectStatusSchema, DataQualityRuleArraySchema, DataQualityRuleResultArraySchema, DataQualityRuleResultSchema, DataQualityRuleSchema, DataQualityRulesSchema, DataQualityStatusByPartitionSchema, DataQualityStatusSchema, DataQualityTimelineEntrySchema, DataQualityTimelineSchema, DatasetCreateOptionsSchema, DatasetDetailsSchema, DatasetSchemaSchema, DatasetSummaryArraySchema, DatasetSummarySchema, FlowMapOptionsSchema, FlowZoneArraySchema, FlowZoneCreateOptionsSchema, FlowZoneItemSchema, FlowZoneObjectTypeSchema, FlowZonePositionSchema, FlowZoneSchema, FlowZoneUpdateOptionsSchema, FolderCreateOptionsSchema, FolderDetailsSchema, FolderItemArraySchema, FolderItemSchema, FolderSummaryArraySchema, FolderSummarySchema, FutureStateSchema, FutureWaitResultSchema, InsightDetailsSchema, InsightSummaryArraySchema, InsightSummarySchema, JobSummaryArraySchema, JobSummarySchema, JobWaitResultSchema, JupyterCellSchema, JupyterNotebookContentSchema, JupyterNotebookSummaryArraySchema, JupyterNotebookSummarySchema, NotebookSessionArraySchema, NotebookSessionSchema, parseSchema, ProjectDetailsSchema, ProjectMetadataSchema, ProjectSummaryArraySchema, ProjectSummarySchema, ProjectVariablesSchema, RecipeCreateOptionsSchema, RecipeCreateResultSchema, RecipeDetailsSchema, RecipeSummaryArraySchema, RecipeSummarySchema, safeParseSchema, ScenarioDetailsSchema, ScenarioStatusSchema, ScenarioSummaryArraySchema, ScenarioSummarySchema, ScenarioWaitResultSchema, SqlNotebookCellSchema, SqlNotebookContentSchema, SqlNotebookSummaryArraySchema, SqlNotebookSummarySchema, SqlQueryResponseSchema, SqlQueryResultSchema, SqlQuerySchemaSchema, WikiArticleDataArraySchema, WikiArticleDataSchema, WikiArticleMetadataSchema, WikiSettingsSchema, WikiTaxonomyNodeSchema, } from "../packages/types/src/index.js";
6
+ export { BuildModeSchema, CodeEnvActionResultSchema, CodeEnvCreateOptionsSchema, CodeEnvDetailsSchema, CodeEnvPackageListSchema, CodeEnvSetPackagesOptionsSchema, CodeEnvSummaryArraySchema, CodeEnvSummarySchema, CodeEnvUpdatePackagesOptionsSchema, CodeEnvUsageArraySchema, CodeEnvWaitOptionsSchema, ConnectionSummarySchema, DashboardDetailsSchema, DashboardSummaryArraySchema, DashboardSummarySchema, DataQualityComputeResultSchema, DataQualityProjectStatusSchema, DataQualityRuleArraySchema, DataQualityRuleResultArraySchema, DataQualityRuleResultSchema, DataQualityRuleSchema, DataQualityRulesSchema, DataQualityStatusByPartitionSchema, DataQualityStatusSchema, DataQualityTimelineEntrySchema, DataQualityTimelineSchema, DatasetCreateOptionsSchema, DatasetDetailsSchema, DatasetSchemaSchema, DatasetSummaryArraySchema, DatasetSummarySchema, FlowMapOptionsSchema, FlowZoneArraySchema, FlowZoneCreateOptionsSchema, FlowZoneItemSchema, FlowZoneObjectTypeSchema, FlowZonePositionSchema, FlowZoneSchema, FlowZoneUpdateOptionsSchema, FolderCreateOptionsSchema, FolderDetailsSchema, FolderItemArraySchema, FolderItemSchema, FolderSummaryArraySchema, FolderSummarySchema, FutureStateSchema, FutureWaitResultSchema, InsightDetailsSchema, InsightSummaryArraySchema, InsightSummarySchema, JobSummaryArraySchema, JobSummarySchema, JobWaitResultSchema, JupyterCellSchema, JupyterNotebookContentSchema, JupyterNotebookSummaryArraySchema, JupyterNotebookSummarySchema, NotebookSessionArraySchema, NotebookSessionSchema, parseSchema, ProjectDetailsSchema, ProjectMetadataSchema, ProjectSummaryArraySchema, ProjectSummarySchema, ProjectVariablesSchema, RecipeCreateOptionsSchema, RecipeCreateResultSchema, RecipeDetailsSchema, RecipeSummaryArraySchema, RecipeSummarySchema, safeParseSchema, ScenarioDetailsSchema, ScenarioStatusSchema, ScenarioStepRunSchema, ScenarioSummaryArraySchema, ScenarioSummarySchema, ScenarioWaitResultSchema, SqlNotebookCellSchema, SqlNotebookContentSchema, SqlNotebookSummaryArraySchema, SqlNotebookSummarySchema, SqlQueryResponseSchema, SqlQueryResultSchema, SqlQuerySchemaSchema, WikiArticleDataArraySchema, WikiArticleDataSchema, WikiArticleMetadataSchema, WikiSettingsSchema, WikiTaxonomyNodeSchema, } from "../packages/types/src/index.js";
package/dist/src/skill.js CHANGED
@@ -87,8 +87,8 @@ Mutations print a small JSON ack to stdout and exit 0 on success (e.g. \`{"updat
87
87
  - Pass code and SQL via \`--file\`/\`--sql-file\`, not inline: shells (especially PowerShell) mangle quotes, \`$\`, and newlines in multi-line snippets.
88
88
  - On a non-UTF-8 console (e.g. Windows cp1252), don't print non-ASCII results; write them to a UTF-8 file and read that, or use \`--output PATH\`.
89
89
  - Build failures: \`dss job log <id> --errors-only\` surfaces just error/traceback lines, and \`--output PATH\` saves the full log to a file. Logs are one long line with JVM noise; the \`Error in Python process: At line <N>\` marker maps \`<N>\` straight to your recipe payload's source line.
90
- - Schema changes aren't automatic: after changing a recipe's output columns run \`dss dataset refresh-schema\` (or rebuild) before downstream reads, and \`dss dataset validate-build\` to catch file-backed misconfig before launching a build.
91
- - \`dss dataset download\` is capped (default 100k rows) and returns \`{ path, rows, truncated, limit }\`: check \`truncated\` and raise \`--limit N\` when you need more — treat it as a sample, not a guaranteed full export. For very large tables, aggregate in SQL or read inside a recipe instead.
90
+ - Schema changes aren't automatic for code recipes: after changing a python/SQL/prepare recipe's output columns run \`dss dataset refresh-schema\` (or rebuild) before downstream reads, and \`dss dataset validate-build\` to catch file-backed misconfig before launching a build. Exception: \`dss recipe create --type sync\` copies the input schema onto a schemaless dataset output at create time (see \`syncOutputSchemaPropagated\` in the result), so a fresh sync output builds populated without a manual refresh.
91
+ - \`dss dataset download\` is capped (default 100k rows) and returns \`{ path, rows, truncated, limit }\`: check \`truncated\` and raise \`--limit N\` when you need more — treat it as a sample, not a guaranteed full export. Without \`--output\` the file lands in the current working directory (and a \`dataset_download_default_location\` warning names that path); pass \`--output PATH\` to control the destination. For very large tables, aggregate in SQL or read inside a recipe instead.
92
92
 
93
93
  ## Error envelope
94
94
 
@@ -4,7 +4,8 @@ export function sanitizeFileName(name, fallback) {
4
4
  const sanitized = name
5
5
  .replace(/[<>:"/\\|?*\u0000-\u001F]/g, "_")
6
6
  .replace(/[. ]+$/g, "")
7
- .trim();
7
+ .trim()
8
+ .replace(/^\.+/, "");
8
9
  if (!sanitized)
9
10
  return fallback;
10
11
  const dotIndex = sanitized.indexOf(".");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dataiku-sdk",
3
- "version": "0.10.1",
3
+ "version": "0.12.0",
4
4
  "description": "Dataiku DSS SDK and CLI for programmatic access to DSS REST APIs",
5
5
  "type": "module",
6
6
  "workspaces": [