dataiku-sdk 0.6.2 → 0.7.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.
@@ -35,7 +35,7 @@ export interface DataikuClientConfig {
35
35
  caCertPath?: string;
36
36
  /**
37
37
  * Called when an API response fails schema validation but data is still usable.
38
- * Default: writes to stderr. Set to a throwing function for strict mode.
38
+ * Default: ignored. Set to a recording or throwing function for strict mode.
39
39
  * @param method - resource method that triggered the warning (e.g. "datasets.list")
40
40
  * @param errors - human-readable validation error strings
41
41
  */
@@ -50,23 +50,23 @@ export declare class DataikuClient {
50
50
  private readonly verbose;
51
51
  private readonly tlsOptions;
52
52
  private readonly onValidationWarning;
53
- private _projects?;
54
- private _datasets?;
55
- private _recipes?;
56
- private _dashboards?;
57
- private _dataQuality?;
58
- private _jobs?;
53
+ private projectsResource?;
54
+ private datasetsResource?;
55
+ private recipesResource?;
56
+ private dashboardsResource?;
57
+ private dataQualityResource?;
58
+ private jobsResource?;
59
59
  private futuresResource?;
60
- private _scenarios?;
61
- private _folders?;
62
- private _flowZones?;
63
- private _variables?;
64
- private _connections?;
65
- private _codeEnvs?;
66
- private _insights?;
67
- private _sql?;
68
- private _notebooks?;
69
- private _wiki?;
60
+ private scenariosResource?;
61
+ private foldersResource?;
62
+ private flowZonesResource?;
63
+ private variablesResource?;
64
+ private connectionsResource?;
65
+ private codeEnvsResource?;
66
+ private insightsResource?;
67
+ private sqlResource?;
68
+ private notebooksResource?;
69
+ private wikiResource?;
70
70
  get projects(): ProjectsResource;
71
71
  get datasets(): DatasetsResource;
72
72
  get dashboards(): DashboardsResource;
@@ -113,6 +113,7 @@ export declare class DataikuClient {
113
113
  safeParse<S extends TSchema>(schema: S, data: unknown, method: string): Static<S>;
114
114
  /** Emit a validation warning via the configured callback. */
115
115
  warn(method: string, errors: string[]): void;
116
+ private requestIdFromHeaders;
116
117
  private parseJsonResponse;
117
118
  private fetchWithRetry;
118
119
  }
@@ -31,8 +31,7 @@ const DEFAULT_REQUEST_TIMEOUT_MS = 30_000;
31
31
  /* ------------------------------------------------------------------ */
32
32
  /* Helpers */
33
33
  /* ------------------------------------------------------------------ */
34
- function defaultValidationWarning(method, errors) {
35
- process.stderr.write(`[dataiku-sdk] Schema validation warning in ${method}:\n ${errors.join("\n ")}\n`);
34
+ function defaultValidationWarning(_method, _errors) {
36
35
  }
37
36
  function sleep(ms) {
38
37
  return new Promise((r) => setTimeout(r, ms));
@@ -92,73 +91,73 @@ export class DataikuClient {
92
91
  tlsOptions;
93
92
  onValidationWarning;
94
93
  /* Resource namespaces — lazily initialized to break circular imports */
95
- _projects;
96
- _datasets;
97
- _recipes;
98
- _dashboards;
99
- _dataQuality;
100
- _jobs;
94
+ projectsResource;
95
+ datasetsResource;
96
+ recipesResource;
97
+ dashboardsResource;
98
+ dataQualityResource;
99
+ jobsResource;
101
100
  futuresResource;
102
- _scenarios;
103
- _folders;
104
- _flowZones;
105
- _variables;
106
- _connections;
107
- _codeEnvs;
108
- _insights;
109
- _sql;
110
- _notebooks;
111
- _wiki;
101
+ scenariosResource;
102
+ foldersResource;
103
+ flowZonesResource;
104
+ variablesResource;
105
+ connectionsResource;
106
+ codeEnvsResource;
107
+ insightsResource;
108
+ sqlResource;
109
+ notebooksResource;
110
+ wikiResource;
112
111
  get projects() {
113
- return (this._projects ??= new ProjectsResource(this));
112
+ return (this.projectsResource ??= new ProjectsResource(this));
114
113
  }
115
114
  get datasets() {
116
- return (this._datasets ??= new DatasetsResource(this));
115
+ return (this.datasetsResource ??= new DatasetsResource(this));
117
116
  }
118
117
  get dashboards() {
119
- return (this._dashboards ??= new DashboardsResource(this));
118
+ return (this.dashboardsResource ??= new DashboardsResource(this));
120
119
  }
121
120
  get dataQuality() {
122
- return (this._dataQuality ??= new DataQualityResource(this));
121
+ return (this.dataQualityResource ??= new DataQualityResource(this));
123
122
  }
124
123
  get recipes() {
125
- return (this._recipes ??= new RecipesResource(this));
124
+ return (this.recipesResource ??= new RecipesResource(this));
126
125
  }
127
126
  get jobs() {
128
- return (this._jobs ??= new JobsResource(this));
127
+ return (this.jobsResource ??= new JobsResource(this));
129
128
  }
130
129
  get futures() {
131
130
  return (this.futuresResource ??= new FuturesResource(this));
132
131
  }
133
132
  get scenarios() {
134
- return (this._scenarios ??= new ScenariosResource(this));
133
+ return (this.scenariosResource ??= new ScenariosResource(this));
135
134
  }
136
135
  get folders() {
137
- return (this._folders ??= new FoldersResource(this));
136
+ return (this.foldersResource ??= new FoldersResource(this));
138
137
  }
139
138
  get flowZones() {
140
- return (this._flowZones ??= new FlowZonesResource(this));
139
+ return (this.flowZonesResource ??= new FlowZonesResource(this));
141
140
  }
142
141
  get variables() {
143
- return (this._variables ??= new VariablesResource(this));
142
+ return (this.variablesResource ??= new VariablesResource(this));
144
143
  }
145
144
  get connections() {
146
- return (this._connections ??= new ConnectionsResource(this));
145
+ return (this.connectionsResource ??= new ConnectionsResource(this));
147
146
  }
148
147
  get codeEnvs() {
149
- return (this._codeEnvs ??= new CodeEnvsResource(this));
148
+ return (this.codeEnvsResource ??= new CodeEnvsResource(this));
150
149
  }
151
150
  get insights() {
152
- return (this._insights ??= new InsightsResource(this));
151
+ return (this.insightsResource ??= new InsightsResource(this));
153
152
  }
154
153
  get sql() {
155
- return (this._sql ??= new SqlResource(this));
154
+ return (this.sqlResource ??= new SqlResource(this));
156
155
  }
157
156
  get notebooks() {
158
- return (this._notebooks ??= new NotebooksResource(this));
157
+ return (this.notebooksResource ??= new NotebooksResource(this));
159
158
  }
160
159
  get wiki() {
161
- return (this._wiki ??= new WikiResource(this));
160
+ return (this.wikiResource ??= new WikiResource(this));
162
161
  }
163
162
  constructor(config) {
164
163
  const url = config.url?.trim();
@@ -298,6 +297,20 @@ export class DataikuClient {
298
297
  this.onValidationWarning(method, errors);
299
298
  }
300
299
  /* ---- private: JSON parsing ---- */
300
+ requestIdFromHeaders(headers) {
301
+ for (const name of [
302
+ "x-request-id",
303
+ "x-dku-request-id",
304
+ "x-dataiku-request-id",
305
+ "x-correlation-id",
306
+ "x-amzn-requestid",
307
+ ]) {
308
+ const value = headers.get(name);
309
+ if (value)
310
+ return value;
311
+ }
312
+ return undefined;
313
+ }
301
314
  async parseJsonResponse(res) {
302
315
  const text = await res.text();
303
316
  // SAFETY: Empty 2xx responses from DSS are surfaced to callers as undefined
@@ -310,7 +323,7 @@ export class DataikuClient {
310
323
  }
311
324
  catch {
312
325
  const summary = text.length > 300 ? `${text.slice(0, 300)}…` : text;
313
- throw new DataikuError(res.status, res.statusText || "Invalid JSON response", `Expected JSON response body but got non-JSON content: ${summary}`);
326
+ throw new DataikuError(res.status, res.statusText || "Invalid JSON response", `Expected JSON response body but got non-JSON content: ${summary}`, undefined, this.requestIdFromHeaders(res.headers));
314
327
  }
315
328
  }
316
329
  /* ---- private: retry loop ---- */
@@ -347,7 +360,7 @@ export class DataikuClient {
347
360
  await sleep(delayMs);
348
361
  continue;
349
362
  }
350
- throw new DataikuError(res.status, res.statusText, text, buildRetryMetadata(method, retryEnabled, maxAttempts, attempt, delaysMs, false));
363
+ throw new DataikuError(res.status, res.statusText, text, buildRetryMetadata(method, retryEnabled, maxAttempts, attempt, delaysMs, false), this.requestIdFromHeaders(res.headers));
351
364
  }
352
365
  return res;
353
366
  }
@@ -9,5 +9,3 @@ export declare function getConfigDir(): string;
9
9
  export declare function getCredentialsPath(): string;
10
10
  export declare function loadCredentials(): DssCredentials | null;
11
11
  export declare function saveCredentials(creds: DssCredentials): void;
12
- export declare function deleteCredentials(): void;
13
- export declare function maskApiKey(apiKey: string): string;
@@ -1,4 +1,4 @@
1
- import { chmodSync, mkdirSync, readFileSync, unlinkSync, writeFileSync, } from "node:fs";
1
+ import { chmodSync, mkdirSync, readFileSync, writeFileSync, } from "node:fs";
2
2
  import { homedir, } from "node:os";
3
3
  import { dirname, join, resolve, } from "node:path";
4
4
  export function getConfigDir() {
@@ -56,18 +56,3 @@ export function saveCredentials(creds) {
56
56
  writeFileSync(path, `${JSON.stringify(data, null, 2)}\n`, "utf-8");
57
57
  chmodSync(path, 0o600);
58
58
  }
59
- export function deleteCredentials() {
60
- try {
61
- unlinkSync(getCredentialsPath());
62
- }
63
- catch (err) {
64
- if (err.code === "ENOENT")
65
- return;
66
- throw err;
67
- }
68
- }
69
- export function maskApiKey(apiKey) {
70
- if (apiKey.length <= 12)
71
- return "***";
72
- return `${apiKey.slice(0, 6)}...${apiKey.slice(-6)}`;
73
- }
@@ -24,7 +24,8 @@ export declare class DataikuError extends Error {
24
24
  retryable: boolean;
25
25
  retryHint: string;
26
26
  retry?: DataikuRetryMetadata;
27
- constructor(status: number, statusText: string, body: string, retry?: DataikuRetryMetadata);
27
+ requestId?: string;
28
+ constructor(status: number, statusText: string, body: string, retry?: DataikuRetryMetadata, requestId?: string);
28
29
  private static extractSummary;
29
30
  private static formatRetryMetadata;
30
31
  private static buildDetails;
@@ -152,7 +152,8 @@ export class DataikuError extends Error {
152
152
  retryable;
153
153
  retryHint;
154
154
  retry;
155
- constructor(status, statusText, body, retry) {
155
+ requestId;
156
+ constructor(status, statusText, body, retry, requestId) {
156
157
  const details = DataikuError.buildDetails(status, statusText, body, retry);
157
158
  super(details.message);
158
159
  this.status = status;
@@ -163,6 +164,7 @@ export class DataikuError extends Error {
163
164
  this.retryable = details.retryable;
164
165
  this.retryHint = details.retryHint;
165
166
  this.retry = retry;
167
+ this.requestId = requestId;
166
168
  }
167
169
  static extractSummary(_status, _statusText, body) {
168
170
  try {
@@ -1,6 +1,6 @@
1
1
  export { DataikuClient, type DataikuClientConfig, } from "./client.js";
2
2
  export { type CredentialValidationOptions, type CredentialValidationResult, validateCredentials, } from "./auth.js";
3
- export { deleteCredentials, type DssCredentials, getConfigDir, getCredentialsPath, loadCredentials, maskApiKey, saveCredentials, } from "./config.js";
3
+ export { type DssCredentials, getConfigDir, getCredentialsPath, loadCredentials, saveCredentials, } from "./config.js";
4
4
  export { DataikuError, type DataikuErrorCategory, type DataikuErrorTaxonomy, type DataikuRetryMetadata, } from "./errors.js";
5
5
  export { CodeEnvsResource, } from "./resources/code-envs.js";
6
6
  export { type ConnectionSchemaListOptions, ConnectionsResource, type ConnectionTableListOptions, } from "./resources/connections.js";
@@ -15,13 +15,13 @@ export { computeNextPollDelayMs, type JobBuildAndWaitOptions, type JobBuildOptio
15
15
  export { NotebooksResource, } from "./resources/notebooks.js";
16
16
  export { type FlowMapResult, ProjectsResource, } from "./resources/projects.js";
17
17
  export { type RecipeCloneOptions, type RecipeCloneResult, type RecipeGraphReference, type RecipeGraphValidationResult, type RecipeRunOptions, type RecipeRunOutput, type RecipeRunResult, RecipesResource, } from "./resources/recipes.js";
18
- export { normalizeScenarioUpdateData, SCENARIO_CANONICAL_EDITABLE_FIELDS, type ScenarioFieldChange, type ScenarioFieldMismatch, ScenariosResource, type ScenarioUpdateNormalization, type ScenarioUpdatePreview, scenarioUpdatePreview, type ScenarioUpdateResult, } from "./resources/scenarios.js";
18
+ export { normalizeScenarioUpdateData, SCENARIO_CANONICAL_EDITABLE_FIELDS, type ScenarioFieldChange, type ScenarioFieldMismatch, type ScenarioScriptRunResult, ScenariosResource, type ScenarioUpdateNormalization, type ScenarioUpdatePreview, scenarioUpdatePreview, type ScenarioUpdateResult, } from "./resources/scenarios.js";
19
19
  export { SqlResource, } from "./resources/sql.js";
20
20
  export { VariablesResource, } from "./resources/variables.js";
21
21
  export { WikiResource, } from "./resources/wiki.js";
22
- 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, SqlNotebookCellSchema, SqlNotebookContentSchema, SqlNotebookSummaryArraySchema, SqlNotebookSummarySchema, SqlQueryResponseSchema, SqlQueryResultSchema, SqlQuerySchemaSchema, WikiArticleDataArraySchema, WikiArticleDataSchema, WikiArticleMetadataSchema, WikiSettingsSchema, WikiTaxonomyNodeSchema, } from "./schemas.js";
22
+ 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 "./schemas.js";
23
23
  export type { SafeParseResult, } from "./schemas.js";
24
- 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, ScenarioDetails, ScenarioStatus, ScenarioSummary, SqlNotebookCell, SqlNotebookContent, SqlNotebookSummary, SqlQueryResponse, SqlQueryResult, SqlQuerySchema, WikiArticleData, WikiArticleMetadata, WikiSettings, WikiTaxonomyNode, } from "./schemas.js";
24
+ 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, ScenarioDetails, ScenarioStatus, ScenarioSummary, ScenarioWaitResult, SqlNotebookCell, SqlNotebookContent, SqlNotebookSummary, SqlQueryResponse, SqlQueryResult, SqlQuerySchema, WikiArticleData, WikiArticleMetadata, WikiSettings, WikiTaxonomyNode, } from "./schemas.js";
25
25
  export { deepMerge, } from "./utils/deep-merge.js";
26
26
  export { type NormalizedFlowEdge, type NormalizedFlowMap, type NormalizedFlowNode, normalizeFlowGraph, } from "./utils/flow-map.js";
27
27
  export { sanitizeFileName, } from "./utils/sanitize.js";
package/dist/src/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  export { DataikuClient, } from "./client.js";
3
3
  // Auth & Config
4
4
  export { validateCredentials, } from "./auth.js";
5
- export { deleteCredentials, getConfigDir, getCredentialsPath, loadCredentials, maskApiKey, saveCredentials, } from "./config.js";
5
+ export { getConfigDir, getCredentialsPath, loadCredentials, saveCredentials, } from "./config.js";
6
6
  // Errors
7
7
  export { DataikuError, } from "./errors.js";
8
8
  // Resources (for advanced use / extension)
@@ -24,7 +24,7 @@ export { SqlResource, } from "./resources/sql.js";
24
24
  export { VariablesResource, } from "./resources/variables.js";
25
25
  export { WikiResource, } from "./resources/wiki.js";
26
26
  // Schemas (TypeBox schema objects for runtime validation)
27
- 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, SqlNotebookCellSchema, SqlNotebookContentSchema, SqlNotebookSummaryArraySchema, SqlNotebookSummarySchema, SqlQueryResponseSchema, SqlQueryResultSchema, SqlQuerySchemaSchema, WikiArticleDataArraySchema, WikiArticleDataSchema, WikiArticleMetadataSchema, WikiSettingsSchema, WikiTaxonomyNodeSchema, } from "./schemas.js";
27
+ 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 "./schemas.js";
28
28
  // Utilities
29
29
  export { deepMerge, } from "./utils/deep-merge.js";
30
30
  export { normalizeFlowGraph, } from "./utils/flow-map.js";
@@ -47,9 +47,9 @@ export declare class DatasetsResource extends BaseResource {
47
47
  /** Replace dataset schema columns directly through the schema endpoint. */
48
48
  updateSchema(datasetName: string, columns: DatasetSchemaColumnInput[], projectKey?: string): Promise<void>;
49
49
  /**
50
- * Preview dataset data as CSV text.
51
- * Streams TSV from the API, converts to CSV, and returns up to `maxRows`
52
- * data rows (plus header).
50
+ * Preview dataset rows as structured data: column names plus row arrays,
51
+ * mirroring the sql query shape ({ columns, rows, rowCount }). Streams TSV
52
+ * from the API and returns up to `maxRows` data rows.
53
53
  *
54
54
  * If `validateColumns` is provided, the first TSV row (header) is checked
55
55
  * against the column names. Mismatches emit a warning via onValidationWarning.
@@ -61,12 +61,20 @@ export declare class DatasetsResource extends BaseResource {
61
61
  name: string;
62
62
  }[];
63
63
  timeoutMs?: number;
64
- }): Promise<string>;
64
+ }): Promise<{
65
+ columns: Array<{
66
+ name: string;
67
+ }>;
68
+ rows: string[][];
69
+ rowCount: number;
70
+ }>;
65
71
  /** Get dataset metadata (tags, custom fields, checklists). */
66
72
  metadata(datasetName: string, projectKey?: string): Promise<Record<string, unknown>>;
67
73
  /**
68
- * Download dataset data as a gzipped CSV file.
69
- * Returns the absolute path of the written file.
74
+ * Download dataset rows as a gzipped (or .csv) file, capped at `limit` rows
75
+ * (default 100k). Returns the written path, the number of data rows written,
76
+ * whether the dataset had more rows than the cap (truncated), and the limit
77
+ * used — so callers can detect truncation instead of silently getting a sample.
70
78
  */
71
79
  download(datasetName: string, opts?: {
72
80
  outputPath?: string;
@@ -74,7 +82,13 @@ export declare class DatasetsResource extends BaseResource {
74
82
  validateColumns?: {
75
83
  name: string;
76
84
  }[];
77
- }): Promise<string>;
85
+ limit?: number;
86
+ }): Promise<{
87
+ path: string;
88
+ rows: number;
89
+ truncated: boolean;
90
+ limit: number;
91
+ }>;
78
92
  /**
79
93
  * Create a new dataset.
80
94
  *
@@ -133,22 +133,6 @@ export function validateStreamColumns(headerRow, expectedColumns) {
133
133
  }
134
134
  return warnings;
135
135
  }
136
- function emitCsvLineWithLimit(row, maxDataRows, emittedRows, onLine, onHeader) {
137
- if (isBlankRow(row))
138
- return false;
139
- const isHeader = emittedRows.value === 0;
140
- if (isHeader && onHeader)
141
- onHeader(row);
142
- if (!isHeader && emittedRows.value - 1 >= maxDataRows) {
143
- return true;
144
- }
145
- onLine(rowToCsv(row));
146
- emittedRows.value += 1;
147
- if (!isHeader && emittedRows.value - 1 >= maxDataRows) {
148
- return true;
149
- }
150
- return false;
151
- }
152
136
  function buildPreviewTimeoutError(timeoutMs) {
153
137
  return new DataikuError(0, "Request Timeout", `Dataset preview timed out after ${timeoutMs}ms while waiting for rows.`);
154
138
  }
@@ -167,13 +151,29 @@ async function readChunkWithTimeout(reader, remainingMs, timeoutMs) {
167
151
  });
168
152
  });
169
153
  }
170
- async function collectPreviewCsv(body, maxDataRows, timeoutMs, onHeader) {
154
+ async function collectPreviewRows(body, maxDataRows, timeoutMs, onHeader) {
171
155
  const state = createTsvStreamState();
172
- const emittedRows = { value: 0, };
173
- const lines = [];
156
+ let columns;
157
+ const rows = [];
174
158
  let done = false;
175
159
  const startedAt = Date.now();
176
160
  const reader = body.getReader();
161
+ const handleRow = (row) => {
162
+ if (done || isBlankRow(row))
163
+ return;
164
+ if (columns === undefined) {
165
+ columns = row;
166
+ onHeader?.(row);
167
+ return;
168
+ }
169
+ if (rows.length >= maxDataRows) {
170
+ done = true;
171
+ return;
172
+ }
173
+ rows.push(row);
174
+ if (rows.length >= maxDataRows)
175
+ done = true;
176
+ };
177
177
  try {
178
178
  while (true) {
179
179
  if (done) {
@@ -186,64 +186,53 @@ async function collectPreviewCsv(body, maxDataRows, timeoutMs, onHeader) {
186
186
  const result = await readChunkWithTimeout(reader, remainingMs, timeoutMs);
187
187
  if (result.done)
188
188
  break;
189
- consumeTsvChunk(Buffer.from(result.value).toString("utf-8"), state, (row) => {
190
- if (done)
191
- return;
192
- done = emitCsvLineWithLimit(row, maxDataRows, emittedRows, (line) => {
193
- lines.push(line);
194
- }, onHeader);
195
- });
189
+ consumeTsvChunk(Buffer.from(result.value).toString("utf-8"), state, handleRow);
196
190
  }
197
- if (!done) {
198
- flushTsvStream(state, (row) => {
199
- if (done)
200
- return;
201
- done = emitCsvLineWithLimit(row, maxDataRows, emittedRows, (line) => {
202
- lines.push(line);
203
- }, onHeader);
204
- });
205
- }
206
- return lines.join("\n");
191
+ if (!done)
192
+ flushTsvStream(state, handleRow);
193
+ return { columns: columns ?? [], rows, };
207
194
  }
208
195
  finally {
209
196
  reader.releaseLock();
210
197
  }
211
198
  }
212
- function tsvToCsvTransform(maxDataRows, onHeader) {
199
+ function tsvToCsvTransform(maxDataRows, stats, onHeader) {
213
200
  const state = createTsvStreamState();
214
- const emittedRows = { value: 0, };
215
- let done = false;
216
201
  const maxRows = Math.max(1, maxDataRows);
202
+ let headerSeen = false;
203
+ let done = false;
204
+ const handleRow = (row, push) => {
205
+ if (done || isBlankRow(row))
206
+ return;
207
+ if (!headerSeen) {
208
+ headerSeen = true;
209
+ onHeader?.(row);
210
+ push(`${rowToCsv(row)}\n`);
211
+ return;
212
+ }
213
+ if (stats.rows >= maxRows) {
214
+ stats.truncated = true;
215
+ done = true;
216
+ return;
217
+ }
218
+ push(`${rowToCsv(row)}\n`);
219
+ stats.rows += 1;
220
+ };
217
221
  return new Transform({
218
222
  transform(chunk, _encoding, callback) {
219
223
  if (done) {
220
224
  callback();
221
225
  return;
222
226
  }
223
- consumeTsvChunk(chunk.toString("utf-8"), state, (row) => {
224
- if (done)
225
- return;
226
- done = emitCsvLineWithLimit(row, maxRows, emittedRows, (line) => {
227
- this.push(`${line}\n`);
228
- }, onHeader);
229
- });
230
- if (done) {
227
+ consumeTsvChunk(chunk.toString("utf-8"), state, (row) => handleRow(row, (line) => this.push(line)));
228
+ if (done)
231
229
  this.push(null);
232
- }
233
230
  callback();
234
231
  },
235
232
  flush(callback) {
236
- if (done) {
237
- callback();
238
- return;
233
+ if (!done) {
234
+ flushTsvStream(state, (row) => handleRow(row, (line) => this.push(line)));
239
235
  }
240
- flushTsvStream(state, (row) => {
241
- if (done)
242
- return;
243
- done = emitCsvLineWithLimit(row, maxRows, emittedRows, (line) => {
244
- this.push(`${line}\n`);
245
- }, onHeader);
246
- });
247
236
  callback();
248
237
  },
249
238
  });
@@ -387,9 +376,9 @@ export class DatasetsResource extends BaseResource {
387
376
  await this.client.put(`/public/api/projects/${this.enc(projectKey)}/datasets/${dsEnc}/schema`, { columns, });
388
377
  }
389
378
  /**
390
- * Preview dataset data as CSV text.
391
- * Streams TSV from the API, converts to CSV, and returns up to `maxRows`
392
- * data rows (plus header).
379
+ * Preview dataset rows as structured data: column names plus row arrays,
380
+ * mirroring the sql query shape ({ columns, rows, rowCount }). Streams TSV
381
+ * from the API and returns up to `maxRows` data rows.
393
382
  *
394
383
  * If `validateColumns` is provided, the first TSV row (header) is checked
395
384
  * against the column names. Mismatches emit a warning via onValidationWarning.
@@ -408,8 +397,9 @@ export class DatasetsResource extends BaseResource {
408
397
  }
409
398
  : undefined;
410
399
  if (!res.body)
411
- return "";
412
- return collectPreviewCsv(res.body, maxRows, timeoutMs, onHeader);
400
+ return { columns: [], rows: [], rowCount: 0, };
401
+ const { columns, rows, } = await collectPreviewRows(res.body, maxRows, timeoutMs, onHeader);
402
+ return { columns: columns.map((name) => ({ name, })), rows, rowCount: rows.length, };
413
403
  }
414
404
  /** Get dataset metadata (tags, custom fields, checklists). */
415
405
  async metadata(datasetName, projectKey) {
@@ -417,13 +407,15 @@ export class DatasetsResource extends BaseResource {
417
407
  return this.client.get(`/public/api/projects/${this.enc(projectKey)}/datasets/${dsEnc}/metadata`);
418
408
  }
419
409
  /**
420
- * Download dataset data as a gzipped CSV file.
421
- * Returns the absolute path of the written file.
410
+ * Download dataset rows as a gzipped (or .csv) file, capped at `limit` rows
411
+ * (default 100k). Returns the written path, the number of data rows written,
412
+ * whether the dataset had more rows than the cap (truncated), and the limit
413
+ * used — so callers can detect truncation instead of silently getting a sample.
422
414
  */
423
415
  async download(datasetName, opts) {
424
- const downloadLimit = 100_000;
416
+ const limit = Math.max(1, opts?.limit ?? 100_000);
425
417
  const dsEnc = encodeURIComponent(datasetName);
426
- const res = await this.client.stream(`/public/api/projects/${this.enc(opts?.projectKey)}/datasets/${dsEnc}/data/?format=tsv-excel-header&limit=${downloadLimit}`);
418
+ const res = await this.client.stream(`/public/api/projects/${this.enc(opts?.projectKey)}/datasets/${dsEnc}/data/?format=tsv-excel-header&limit=${limit + 1}`);
427
419
  const safeDatasetName = sanitizeFileName(datasetName, "dataset");
428
420
  const filePath = opts?.outputPath?.endsWith(".gz") || opts?.outputPath?.endsWith(".csv")
429
421
  ? resolve(opts.outputPath)
@@ -437,8 +429,9 @@ export class DatasetsResource extends BaseResource {
437
429
  }
438
430
  : undefined;
439
431
  const shouldGzip = filePath.endsWith(".gz");
432
+ const stats = { rows: 0, truncated: false, };
440
433
  const nodeStream = Readable.fromWeb(res.body);
441
- const csvTransform = tsvToCsvTransform(downloadLimit, onHeader);
434
+ const csvTransform = tsvToCsvTransform(limit, stats, onHeader);
442
435
  const fileOut = createWriteStream(filePath);
443
436
  if (shouldGzip) {
444
437
  const gzip = createGzip();
@@ -447,7 +440,7 @@ export class DatasetsResource extends BaseResource {
447
440
  else {
448
441
  await pipeline(nodeStream, csvTransform, fileOut);
449
442
  }
450
- return filePath;
443
+ return { path: filePath, rows: stats.rows, truncated: stats.truncated, limit, };
451
444
  }
452
445
  /**
453
446
  * Create a new dataset.
@@ -62,6 +62,7 @@ export declare class JobsResource extends BaseResource {
62
62
  log(jobId: string, opts?: {
63
63
  activity?: string;
64
64
  logId?: string;
65
+ logFilter?: JobLogFilter;
65
66
  maxLogLines?: number;
66
67
  projectKey?: string;
67
68
  }): Promise<string>;
@@ -181,7 +181,7 @@ export class JobsResource extends BaseResource {
181
181
  // DSS cat-activity-log URLs require a browser session; API-key callers must use the public log endpoint.
182
182
  const path = `/public/api/projects/${this.enc(opts?.projectKey)}/jobs/${jobEnc}/log/${query}`;
183
183
  const log = await this.client.getText(path);
184
- return limitJobLog(log, opts?.maxLogLines);
184
+ return limitJobLog(filterJobLog(log, opts?.logFilter), opts?.maxLogLines);
185
185
  }
186
186
  async logFromUrl(logUrl, opts) {
187
187
  const parsed = new URL(logUrl, "http://dss.local");