dataiku-sdk 3.1.0 → 3.3.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 (149) hide show
  1. package/README.md +253 -38
  2. package/dist/build-metadata.json +1 -1
  3. package/dist/packages/types/src/index.d.ts +102 -0
  4. package/dist/packages/types/src/index.js +76 -0
  5. package/dist/src/auth.js +1 -1
  6. package/dist/src/cli/coerce.js +11 -2
  7. package/dist/src/cli/commands/analysis.js +4 -3
  8. package/dist/src/cli/commands/api-service.js +5 -3
  9. package/dist/src/cli/commands/app.js +61 -18
  10. package/dist/src/cli/commands/bundle.js +3 -2
  11. package/dist/src/cli/commands/code-env.js +23 -16
  12. package/dist/src/cli/commands/connection.d.ts +9 -0
  13. package/dist/src/cli/commands/connection.js +267 -1
  14. package/dist/src/cli/commands/dashboard.js +7 -6
  15. package/dist/src/cli/commands/data-collection.d.ts +2 -0
  16. package/dist/src/cli/commands/data-collection.js +164 -0
  17. package/dist/src/cli/commands/data-quality.js +9 -8
  18. package/dist/src/cli/commands/dataset.js +170 -40
  19. package/dist/src/cli/commands/doctor.js +4 -2
  20. package/dist/src/cli/commands/flow-zone.js +9 -8
  21. package/dist/src/cli/commands/folder.js +9 -8
  22. package/dist/src/cli/commands/future.js +4 -3
  23. package/dist/src/cli/commands/group.d.ts +2 -0
  24. package/dist/src/cli/commands/group.js +109 -0
  25. package/dist/src/cli/commands/index.js +151 -78
  26. package/dist/src/cli/commands/insight.js +8 -7
  27. package/dist/src/cli/commands/job.js +4 -3
  28. package/dist/src/cli/commands/knowledge-bank.d.ts +2 -0
  29. package/dist/src/cli/commands/knowledge-bank.js +80 -0
  30. package/dist/src/cli/commands/llm.d.ts +2 -0
  31. package/dist/src/cli/commands/llm.js +93 -0
  32. package/dist/src/cli/commands/macro.d.ts +2 -0
  33. package/dist/src/cli/commands/macro.js +221 -0
  34. package/dist/src/cli/commands/meaning.js +5 -4
  35. package/dist/src/cli/commands/ml-task.js +21 -8
  36. package/dist/src/cli/commands/model-evaluation-store.js +4 -3
  37. package/dist/src/cli/commands/notebook.js +17 -12
  38. package/dist/src/cli/commands/plugin.d.ts +2 -0
  39. package/dist/src/cli/commands/plugin.js +799 -0
  40. package/dist/src/cli/commands/project-folder.d.ts +2 -0
  41. package/dist/src/cli/commands/project-folder.js +197 -0
  42. package/dist/src/cli/commands/project-git.js +14 -54
  43. package/dist/src/cli/commands/project-library.js +7 -6
  44. package/dist/src/cli/commands/project.js +55 -8
  45. package/dist/src/cli/commands/recipe.js +50 -14
  46. package/dist/src/cli/commands/saved-model.d.ts +5 -0
  47. package/dist/src/cli/commands/saved-model.js +392 -4
  48. package/dist/src/cli/commands/scenario.js +147 -9
  49. package/dist/src/cli/commands/sql.js +3 -2
  50. package/dist/src/cli/commands/statistics.js +7 -6
  51. package/dist/src/cli/commands/user.d.ts +8 -0
  52. package/dist/src/cli/commands/user.js +296 -0
  53. package/dist/src/cli/commands/variable.js +2 -1
  54. package/dist/src/cli/commands/webapp.js +2 -1
  55. package/dist/src/cli/commands/wiki.js +7 -6
  56. package/dist/src/cli/contract.d.ts +2 -3
  57. package/dist/src/cli/contract.js +1167 -163
  58. package/dist/src/cli/flags.d.ts +4 -0
  59. package/dist/src/cli/flags.js +50 -2
  60. package/dist/src/cli/helpers/app-successor.d.ts +19 -4
  61. package/dist/src/cli/helpers/app-successor.js +90 -30
  62. package/dist/src/cli/helpers/cleanup.js +3 -1
  63. package/dist/src/cli/helpers/flow-zone.js +1 -2
  64. package/dist/src/cli/output.d.ts +1 -1
  65. package/dist/src/cli/output.js +23 -10
  66. package/dist/src/cli/usage.d.ts +1 -0
  67. package/dist/src/cli/usage.js +47 -1
  68. package/dist/src/cli.js +225 -95
  69. package/dist/src/client.d.ts +86 -6
  70. package/dist/src/client.js +263 -50
  71. package/dist/src/errors.d.ts +3 -0
  72. package/dist/src/errors.js +4 -0
  73. package/dist/src/index.d.ts +16 -7
  74. package/dist/src/index.js +11 -2
  75. package/dist/src/resources/analyses.js +1 -8
  76. package/dist/src/resources/applications.d.ts +8 -6
  77. package/dist/src/resources/applications.js +21 -21
  78. package/dist/src/resources/base.d.ts +4 -0
  79. package/dist/src/resources/base.js +15 -0
  80. package/dist/src/resources/bundles.d.ts +9 -4
  81. package/dist/src/resources/bundles.js +10 -5
  82. package/dist/src/resources/connections.d.ts +78 -1
  83. package/dist/src/resources/connections.js +132 -1
  84. package/dist/src/resources/data-collections.d.ts +118 -0
  85. package/dist/src/resources/data-collections.js +49 -0
  86. package/dist/src/resources/datasets.d.ts +69 -0
  87. package/dist/src/resources/datasets.js +99 -1
  88. package/dist/src/resources/folders.js +2 -1
  89. package/dist/src/resources/futures.d.ts +4 -1
  90. package/dist/src/resources/futures.js +38 -6
  91. package/dist/src/resources/groups.d.ts +47 -0
  92. package/dist/src/resources/groups.js +56 -0
  93. package/dist/src/resources/jobs.d.ts +8 -13
  94. package/dist/src/resources/jobs.js +41 -16
  95. package/dist/src/resources/knowledge-banks.d.ts +58 -0
  96. package/dist/src/resources/knowledge-banks.js +61 -0
  97. package/dist/src/resources/llms.d.ts +92 -0
  98. package/dist/src/resources/llms.js +62 -0
  99. package/dist/src/resources/macros.d.ts +121 -0
  100. package/dist/src/resources/macros.js +231 -0
  101. package/dist/src/resources/ml-tasks.d.ts +37 -2
  102. package/dist/src/resources/ml-tasks.js +100 -20
  103. package/dist/src/resources/model-evaluation-stores.js +1 -8
  104. package/dist/src/resources/notebooks.d.ts +43 -7
  105. package/dist/src/resources/notebooks.js +53 -13
  106. package/dist/src/resources/plugins.d.ts +265 -0
  107. package/dist/src/resources/plugins.js +458 -0
  108. package/dist/src/resources/project-folders.d.ts +71 -0
  109. package/dist/src/resources/project-folders.js +57 -0
  110. package/dist/src/resources/project-git.d.ts +6 -0
  111. package/dist/src/resources/project-git.js +69 -42
  112. package/dist/src/resources/project-library.d.ts +0 -1
  113. package/dist/src/resources/project-library.js +1 -17
  114. package/dist/src/resources/projects.d.ts +19 -3
  115. package/dist/src/resources/projects.js +30 -18
  116. package/dist/src/resources/recipes.d.ts +15 -1
  117. package/dist/src/resources/recipes.js +73 -6
  118. package/dist/src/resources/saved-models.d.ts +134 -1
  119. package/dist/src/resources/saved-models.js +214 -6
  120. package/dist/src/resources/scenarios.d.ts +105 -0
  121. package/dist/src/resources/scenarios.js +232 -106
  122. package/dist/src/resources/sql.js +5 -1
  123. package/dist/src/resources/users.d.ts +129 -0
  124. package/dist/src/resources/users.js +128 -0
  125. package/dist/src/resources/webapps.d.ts +15 -2
  126. package/dist/src/resources/webapps.js +18 -4
  127. package/dist/src/schemas.d.ts +2 -2
  128. package/dist/src/schemas.js +1 -1
  129. package/dist/src/skill.d.ts +13 -4
  130. package/dist/src/skill.js +75 -24
  131. package/dist/src/utils/deep-merge.d.ts +1 -1
  132. package/dist/src/utils/polling.d.ts +20 -0
  133. package/dist/src/utils/polling.js +27 -0
  134. package/dist/src/utils/response-file.d.ts +2 -0
  135. package/dist/src/utils/response-file.js +34 -0
  136. package/dist/src/utils/secret-sanitize.d.ts +54 -0
  137. package/dist/src/utils/secret-sanitize.js +101 -0
  138. package/package.json +8 -5
  139. package/packages/types/dist/index.d.ts +102 -0
  140. package/packages/types/dist/index.js +76 -0
  141. package/plugin.json +1 -1
  142. package/skills/dataiku-dss/SKILL.md +47 -225
  143. package/skills/dataiku-dss/references/app-releases.md +28 -0
  144. package/skills/dataiku-dss/references/authentication.md +39 -0
  145. package/skills/dataiku-dss/references/coding.md +8 -0
  146. package/skills/dataiku-dss/references/discovery.md +30 -0
  147. package/skills/dataiku-dss/references/flow-maps.md +12 -0
  148. package/skills/dataiku-dss/references/mutations.md +33 -0
  149. package/skills/dataiku-dss/references/troubleshooting.md +29 -0
@@ -48,10 +48,23 @@ export declare class WebappsResource extends BaseResource {
48
48
  /**
49
49
  * Start or restart a webapp backend. The documented endpoint returns a
50
50
  * reference to a future, which is surfaced as-is; settle it with
51
- * {@link restartBackendAndWait} or `client.futures.wait`.
51
+ * {@link restartBackendAndWait} or `client.futures.wait`. DSS 15 returns
52
+ * an empty body (no future) when no async job was spawned — the official
53
+ * Python client tolerates that (`DSSFuture.from_resp` accepts a missing
54
+ * jobId), so an empty response surfaces as `{}` rather than crashing.
52
55
  */
53
56
  startOrRestartBackend(webappId: string, projectKey?: string): Promise<Record<string, unknown>>;
54
- /** Restart a webapp backend and wait for the returned future to settle. */
57
+ /**
58
+ * Restart a webapp backend and wait for the returned future to settle.
59
+ * The documented endpoint returns a reference to a future; with a real
60
+ * jobId this polls that future to completion. An empty response carries
61
+ * NO future to wait on (observed on DSS 15 for a webapp whose backend is
62
+ * not enabled — a no-op restart, not a supported wait target), so the
63
+ * wait reports the missing future explicitly instead of fabricating a
64
+ * result for it. Enable the backend (params.backendEnabled with the
65
+ * params.python code, exactly as the DSS editor does) to get a real
66
+ * restart future.
67
+ */
55
68
  restartBackendAndWait(webappId: string, projectKey?: string, options?: WebappWaitOptions): Promise<FutureWaitResult>;
56
69
  /** Get a webapp backend's state. */
57
70
  getBackendState(webappId: string, projectKey?: string): Promise<Record<string, unknown>>;
@@ -59,18 +59,32 @@ export class WebappsResource extends BaseResource {
59
59
  /**
60
60
  * Start or restart a webapp backend. The documented endpoint returns a
61
61
  * reference to a future, which is surfaced as-is; settle it with
62
- * {@link restartBackendAndWait} or `client.futures.wait`.
62
+ * {@link restartBackendAndWait} or `client.futures.wait`. DSS 15 returns
63
+ * an empty body (no future) when no async job was spawned — the official
64
+ * Python client tolerates that (`DSSFuture.from_resp` accepts a missing
65
+ * jobId), so an empty response surfaces as `{}` rather than crashing.
63
66
  */
64
67
  async startOrRestartBackend(webappId, projectKey) {
65
68
  const id = encodeURIComponent(webappId);
66
- return this.client.put(`/public/api/projects/${this.enc(projectKey)}/webapps/${id}/backend/actions/restart`, {});
69
+ const future = await this.client.put(`/public/api/projects/${this.enc(projectKey)}/webapps/${id}/backend/actions/restart`, {});
70
+ return future ?? {};
67
71
  }
68
- /** Restart a webapp backend and wait for the returned future to settle. */
72
+ /**
73
+ * Restart a webapp backend and wait for the returned future to settle.
74
+ * The documented endpoint returns a reference to a future; with a real
75
+ * jobId this polls that future to completion. An empty response carries
76
+ * NO future to wait on (observed on DSS 15 for a webapp whose backend is
77
+ * not enabled — a no-op restart, not a supported wait target), so the
78
+ * wait reports the missing future explicitly instead of fabricating a
79
+ * result for it. Enable the backend (params.backendEnabled with the
80
+ * params.python code, exactly as the DSS editor does) to get a real
81
+ * restart future.
82
+ */
69
83
  async restartBackendAndWait(webappId, projectKey, options = {}) {
70
84
  const future = await this.startOrRestartBackend(webappId, projectKey);
71
85
  const jobId = future.jobId;
72
86
  if (typeof jobId !== "string" || jobId.length === 0) {
73
- throw new Error("Webapp backend restart did not return a future jobId.");
87
+ throw new ClientValidationError("Webapp backend restart returned no future jobId, so there is nothing to wait on.", "validation_failed", "The restart endpoint returns a future reference only when it starts an async job (a webapp with an enabled Python backend). Enable the backend before restarting with --wait.", { webappId, restartResponseKeys: Object.keys(future), });
74
88
  }
75
89
  return this.client.futures.wait(jobId, {
76
90
  pollIntervalMs: options.pollIntervalMs,
@@ -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, CodeEnvGetLogOptionsSchema, CodeEnvLogResultSchema, CodeEnvLogSummaryArraySchema, CodeEnvLogSummarySchema, CodeEnvPackageListSchema, CodeEnvSetPackagesOptionsSchema, CodeEnvSummaryArraySchema, CodeEnvSummarySchema, CodeEnvUpdateImagesOptionsSchema, CodeEnvUpdatePackagesOptionsSchema, CodeEnvUsageArraySchema, CodeEnvVersionForProjectSchema, 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, ProjectGitActionResultSchema, ProjectGitDiffResultSchema, ProjectGitFutureResponseSchema, ProjectGitFutureStateSchema, ProjectGitLibrariesSchema, ProjectGitLibrarySchema, ProjectGitLogResultSchema, ProjectGitRemoteSchema, ProjectGitStatusSchema, ProjectGitTagSchema, ProjectGitTagsSchema, ProjectMetadataSchema, ProjectSummaryArraySchema, ProjectSummarySchema, ProjectVariablesSchema, RecipeCreateOptionsSchema, RecipeCreateResultSchema, RecipeDetailsSchema, RecipeSummaryArraySchema, RecipeSummarySchema, safeParseSchema, ScenarioDetailsSchema, ScenarioStatusSchema, ScenarioStepRunSchema, ScenarioSummaryArraySchema, ScenarioSummarySchema, ScenarioWaitResultSchema, SqlNotebookCellSchema, SqlNotebookContentSchema, SqlNotebookHistorySchema, SqlNotebookSummaryArraySchema, SqlNotebookSummarySchema, SqlQueryResponseSchema, SqlQueryResultSchema, SqlQuerySchemaSchema, WikiArticleDataArraySchema, WikiArticleDataSchema, WikiArticleMetadataSchema, WikiSettingsSchema, WikiTaxonomyNodeSchema, } from "../packages/types/src/index.js";
7
- export type { BuildMode, CodeEnvActionResult, CodeEnvCreateOptions, CodeEnvDetails, CodeEnvGetLogOptions, CodeEnvLogResult, CodeEnvLogSummary, CodeEnvPackageList, CodeEnvSetPackagesOptions, CodeEnvSummary, CodeEnvUpdateImagesOptions, CodeEnvUpdatePackagesOptions, CodeEnvUsage, CodeEnvVersionForProject, 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, ProjectGitActionResult, ProjectGitDiffResult, ProjectGitFutureResponse, ProjectGitFutureState, ProjectGitLibraries, ProjectGitLibrary, ProjectGitLogResult, ProjectGitRemote, ProjectGitStatus, ProjectGitTag, ProjectGitTags, ProjectMetadata, ProjectSummary, ProjectVariables, RecipeCreateOptions, RecipeCreateResult, RecipeDetails, RecipeSummary, SafeParseResult, ScenarioDetails, ScenarioStatus, ScenarioStepRun, ScenarioSummary, ScenarioWaitResult, SqlNotebookCell, SqlNotebookContent, SqlNotebookHistory, SqlNotebookSummary, SqlQueryResponse, SqlQueryResult, SqlQuerySchema, WikiArticleData, WikiArticleMetadata, WikiSettings, WikiTaxonomyNode, } from "../packages/types/src/index.js";
6
+ export { BuildModeSchema, CodeEnvActionResultSchema, CodeEnvCreateOptionsSchema, CodeEnvDetailsSchema, CodeEnvGetLogOptionsSchema, CodeEnvLogResultSchema, CodeEnvLogSummaryArraySchema, CodeEnvLogSummarySchema, CodeEnvPackageListSchema, CodeEnvSetPackagesOptionsSchema, CodeEnvSummaryArraySchema, CodeEnvSummarySchema, CodeEnvUpdateImagesOptionsSchema, CodeEnvUpdatePackagesOptionsSchema, CodeEnvUsageArraySchema, CodeEnvVersionForProjectSchema, 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, MacroDefinitionSchema, MacroRunStartSchema, MacroStateSchema, MacroSummaryArraySchema, MacroSummarySchema, MacroWaitResultSchema, NotebookSessionArraySchema, NotebookSessionSchema, parseSchema, ProjectDetailsSchema, ProjectGitActionResultSchema, ProjectGitDiffResultSchema, ProjectGitFutureResponseSchema, ProjectGitFutureStateSchema, ProjectGitLibrariesSchema, ProjectGitLibrarySchema, ProjectGitLogResultSchema, ProjectGitRemoteSchema, ProjectGitStatusSchema, ProjectGitTagSchema, ProjectGitTagsSchema, ProjectMetadataSchema, ProjectSummaryArraySchema, ProjectSummarySchema, ProjectTagsSchema, ProjectVariablesSchema, RecipeCreateOptionsSchema, RecipeCreateResultSchema, RecipeDetailsSchema, RecipeSummaryArraySchema, RecipeSummarySchema, safeParseSchema, ScenarioDetailsSchema, ScenarioStatusSchema, ScenarioStepRunSchema, ScenarioSummaryArraySchema, ScenarioSummarySchema, ScenarioWaitResultSchema, SqlNotebookCellSchema, SqlNotebookContentSchema, SqlNotebookHistorySchema, SqlNotebookSummaryArraySchema, SqlNotebookSummarySchema, SqlQueryResponseSchema, SqlQueryResultSchema, SqlQuerySchemaSchema, WikiArticleDataArraySchema, WikiArticleDataSchema, WikiArticleMetadataSchema, WikiSettingsSchema, WikiTaxonomyNodeSchema, } from "../packages/types/src/index.js";
7
+ export type { BuildMode, CodeEnvActionResult, CodeEnvCreateOptions, CodeEnvDetails, CodeEnvGetLogOptions, CodeEnvLogResult, CodeEnvLogSummary, CodeEnvPackageList, CodeEnvSetPackagesOptions, CodeEnvSummary, CodeEnvUpdateImagesOptions, CodeEnvUpdatePackagesOptions, CodeEnvUsage, CodeEnvVersionForProject, 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, MacroDefinition, MacroRunStart, MacroState, MacroSummary, MacroSummaryArray, MacroWaitResult, NotebookSession, ProjectDetails, ProjectGitActionResult, ProjectGitDiffResult, ProjectGitFutureResponse, ProjectGitFutureState, ProjectGitLibraries, ProjectGitLibrary, ProjectGitLogResult, ProjectGitRemote, ProjectGitStatus, ProjectGitTag, ProjectGitTags, ProjectMetadata, ProjectSummary, ProjectTags, ProjectVariables, RecipeCreateOptions, RecipeCreateResult, RecipeDetails, RecipeSummary, SafeParseResult, ScenarioDetails, ScenarioStatus, ScenarioStepRun, ScenarioSummary, ScenarioWaitResult, SqlNotebookCell, SqlNotebookContent, SqlNotebookHistory, 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, CodeEnvGetLogOptionsSchema, CodeEnvLogResultSchema, CodeEnvLogSummaryArraySchema, CodeEnvLogSummarySchema, CodeEnvPackageListSchema, CodeEnvSetPackagesOptionsSchema, CodeEnvSummaryArraySchema, CodeEnvSummarySchema, CodeEnvUpdateImagesOptionsSchema, CodeEnvUpdatePackagesOptionsSchema, CodeEnvUsageArraySchema, CodeEnvVersionForProjectSchema, 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, ProjectGitActionResultSchema, ProjectGitDiffResultSchema, ProjectGitFutureResponseSchema, ProjectGitFutureStateSchema, ProjectGitLibrariesSchema, ProjectGitLibrarySchema, ProjectGitLogResultSchema, ProjectGitRemoteSchema, ProjectGitStatusSchema, ProjectGitTagSchema, ProjectGitTagsSchema, ProjectMetadataSchema, ProjectSummaryArraySchema, ProjectSummarySchema, ProjectVariablesSchema, RecipeCreateOptionsSchema, RecipeCreateResultSchema, RecipeDetailsSchema, RecipeSummaryArraySchema, RecipeSummarySchema, safeParseSchema, ScenarioDetailsSchema, ScenarioStatusSchema, ScenarioStepRunSchema, ScenarioSummaryArraySchema, ScenarioSummarySchema, ScenarioWaitResultSchema, SqlNotebookCellSchema, SqlNotebookContentSchema, SqlNotebookHistorySchema, SqlNotebookSummaryArraySchema, SqlNotebookSummarySchema, SqlQueryResponseSchema, SqlQueryResultSchema, SqlQuerySchemaSchema, WikiArticleDataArraySchema, WikiArticleDataSchema, WikiArticleMetadataSchema, WikiSettingsSchema, WikiTaxonomyNodeSchema, } from "../packages/types/src/index.js";
6
+ export { BuildModeSchema, CodeEnvActionResultSchema, CodeEnvCreateOptionsSchema, CodeEnvDetailsSchema, CodeEnvGetLogOptionsSchema, CodeEnvLogResultSchema, CodeEnvLogSummaryArraySchema, CodeEnvLogSummarySchema, CodeEnvPackageListSchema, CodeEnvSetPackagesOptionsSchema, CodeEnvSummaryArraySchema, CodeEnvSummarySchema, CodeEnvUpdateImagesOptionsSchema, CodeEnvUpdatePackagesOptionsSchema, CodeEnvUsageArraySchema, CodeEnvVersionForProjectSchema, 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, MacroDefinitionSchema, MacroRunStartSchema, MacroStateSchema, MacroSummaryArraySchema, MacroSummarySchema, MacroWaitResultSchema, NotebookSessionArraySchema, NotebookSessionSchema, parseSchema, ProjectDetailsSchema, ProjectGitActionResultSchema, ProjectGitDiffResultSchema, ProjectGitFutureResponseSchema, ProjectGitFutureStateSchema, ProjectGitLibrariesSchema, ProjectGitLibrarySchema, ProjectGitLogResultSchema, ProjectGitRemoteSchema, ProjectGitStatusSchema, ProjectGitTagSchema, ProjectGitTagsSchema, ProjectMetadataSchema, ProjectSummaryArraySchema, ProjectSummarySchema, ProjectTagsSchema, ProjectVariablesSchema, RecipeCreateOptionsSchema, RecipeCreateResultSchema, RecipeDetailsSchema, RecipeSummaryArraySchema, RecipeSummarySchema, safeParseSchema, ScenarioDetailsSchema, ScenarioStatusSchema, ScenarioStepRunSchema, ScenarioSummaryArraySchema, ScenarioSummarySchema, ScenarioWaitResultSchema, SqlNotebookCellSchema, SqlNotebookContentSchema, SqlNotebookHistorySchema, SqlNotebookSummaryArraySchema, SqlNotebookSummarySchema, SqlQueryResponseSchema, SqlQueryResultSchema, SqlQuerySchemaSchema, WikiArticleDataArraySchema, WikiArticleDataSchema, WikiArticleMetadataSchema, WikiSettingsSchema, WikiTaxonomyNodeSchema, } from "../packages/types/src/index.js";
@@ -29,18 +29,27 @@ export declare function detectAgents(): DetectedAgent[];
29
29
  */
30
30
  export declare function findWorkspaceRoot(startDir: string): string;
31
31
  export type SkillStatus = "missing" | "stale" | "current";
32
+ export interface InstalledSkillFile {
33
+ relativePath: string;
34
+ path: string;
35
+ status: SkillStatus;
36
+ changed: boolean;
37
+ expectedSha256: string;
38
+ actualSha256?: string;
39
+ }
32
40
  export interface InstallResult {
33
41
  agent: string;
34
42
  path: string;
35
43
  via: DetectedAgent["via"];
36
- /** Deterministic state of the destination file relative to the canonical skill content. */
44
+ /** Missing entrypoint, incomplete/different bundle, or entirely current bundle. */
37
45
  status: SkillStatus;
38
- /** Whether an install run would (or did) write the destination file. */
46
+ /** Whether any bundled file would (or did) change. Unmanaged files are preserved. */
39
47
  changed: boolean;
40
- /** SHA-256 hex of the canonical skill bytes this installation writes. */
48
+ /** SHA-256 of the canonical SKILL.md entrypoint, not the whole bundle. */
41
49
  expectedSha256: string;
42
- /** SHA-256 hex of the destination file when it exists; absent when status is "missing". */
50
+ /** Hash of the existing entrypoint; absent when that file is missing. */
43
51
  actualSha256?: string;
52
+ files: InstalledSkillFile[];
44
53
  }
45
54
  export declare function planSkillInstalls(agents: DetectedAgent[], opts: {
46
55
  global: boolean;
package/dist/src/skill.js CHANGED
@@ -2,17 +2,21 @@ import { createHash, } from "node:crypto";
2
2
  import * as fs from "node:fs";
3
3
  import * as os from "node:os";
4
4
  import * as path from "node:path";
5
+ import { fileURLToPath, } from "node:url";
5
6
  const SKILL_URLS = [
6
7
  new URL("../skills/dataiku-dss/SKILL.md", import.meta.url),
7
8
  new URL("../../skills/dataiku-dss/SKILL.md", import.meta.url),
8
9
  ];
9
- function skillContent() {
10
+ function skillDirectory() {
10
11
  for (const skillUrl of SKILL_URLS) {
11
12
  if (fs.existsSync(skillUrl))
12
- return fs.readFileSync(skillUrl, "utf-8");
13
+ return new URL("./", skillUrl);
13
14
  }
14
15
  throw new Error(`Bundled Dataiku skill not found. Checked: ${SKILL_URLS.map((url) => url.pathname).join(", ")}`);
15
16
  }
17
+ function skillContent() {
18
+ return fs.readFileSync(new URL("SKILL.md", skillDirectory()), "utf-8");
19
+ }
16
20
  export const AGENTS = {
17
21
  claude: {
18
22
  name: "Claude Code",
@@ -110,7 +114,27 @@ function skillState(target, expectedSha256) {
110
114
  actualSha256,
111
115
  };
112
116
  }
113
- export function planSkillInstalls(agents, opts) {
117
+ /** Load the packaged tree, keeping portable relative paths in the report. */
118
+ function skillFiles() {
119
+ const root = fileURLToPath(skillDirectory());
120
+ const files = new Map();
121
+ function visit(relativeDir) {
122
+ const dir = path.join(root, relativeDir);
123
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true, }).sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0)) {
124
+ const relativePath = relativeDir ? `${relativeDir}/${entry.name}` : entry.name;
125
+ if (entry.isDirectory())
126
+ visit(relativePath);
127
+ else if (entry.isFile()) {
128
+ files.set(relativePath, fs.readFileSync(path.join(root, relativePath)));
129
+ }
130
+ else
131
+ throw new Error(`Unsupported bundled skill entry: ${relativePath}`);
132
+ }
133
+ }
134
+ visit("");
135
+ return files;
136
+ }
137
+ function skillInstallPlan(agents, opts, bundle) {
114
138
  const home = os.homedir();
115
139
  const results = [];
116
140
  for (const { id, def, via, } of agents) {
@@ -121,38 +145,65 @@ export function planSkillInstalls(agents, opts) {
121
145
  : undefined;
122
146
  if (!dir)
123
147
  continue;
124
- const target = path.join(dir, def.filename);
125
- const expectedSha256 = sha256Hex(def.content());
126
- const state = skillState(target, expectedSha256);
148
+ const files = [];
149
+ for (const [sourcePath, source,] of bundle) {
150
+ const relativePath = sourcePath === "SKILL.md" ? def.filename : sourcePath;
151
+ const target = path.join(dir, relativePath);
152
+ const expectedSha256 = sha256Hex(sourcePath === "SKILL.md" ? def.content() : source);
153
+ const state = skillState(target, expectedSha256);
154
+ files.push({
155
+ relativePath,
156
+ path: target,
157
+ ...state,
158
+ changed: state.status !== "current",
159
+ expectedSha256,
160
+ });
161
+ }
162
+ const entrypoint = files.find((file) => file.relativePath === def.filename);
163
+ const changed = files.some((file) => file.changed);
127
164
  results.push({
128
165
  agent: id,
129
- path: target,
166
+ path: entrypoint.path,
130
167
  via,
131
- ...state,
132
- changed: state.status !== "current",
133
- expectedSha256,
168
+ status: entrypoint.status === "missing" ? "missing" : changed ? "stale" : "current",
169
+ changed,
170
+ expectedSha256: entrypoint.expectedSha256,
171
+ ...(entrypoint.actualSha256 !== undefined ? { actualSha256: entrypoint.actualSha256, } : {}),
172
+ files,
134
173
  });
135
174
  }
136
175
  return results;
137
176
  }
177
+ export function planSkillInstalls(agents, opts) {
178
+ return skillInstallPlan(agents, opts, skillFiles());
179
+ }
180
+ function writeSkillFile(file, content) {
181
+ if (!file.changed)
182
+ return;
183
+ const dir = path.dirname(file.path);
184
+ fs.mkdirSync(dir, { recursive: true, });
185
+ const tmpPath = path.join(dir, `.${path.basename(file.path)}.tmp-${process.pid}-${Date.now().toString(36)}`);
186
+ try {
187
+ fs.writeFileSync(tmpPath, content);
188
+ fs.renameSync(tmpPath, file.path);
189
+ }
190
+ finally {
191
+ fs.rmSync(tmpPath, { force: true, });
192
+ }
193
+ }
138
194
  export function installSkill(agents, opts) {
139
- const results = planSkillInstalls(agents, opts);
195
+ const bundle = skillFiles();
196
+ const results = skillInstallPlan(agents, opts, bundle);
140
197
  for (const result of results) {
141
- const def = AGENTS[result.agent];
142
- if (!def || !result.changed)
198
+ if (!result.changed)
143
199
  continue;
144
- const content = def.content();
145
- const dir = path.dirname(result.path);
146
- fs.mkdirSync(dir, { recursive: true, });
147
- const tmpPath = path.join(dir, `.${path.basename(result.path)}.tmp-${process.pid}-${Date.now().toString(36)}`);
148
- fs.writeFileSync(tmpPath, content, "utf-8");
149
- try {
150
- fs.renameSync(tmpPath, result.path);
151
- }
152
- catch (error) {
153
- fs.rmSync(tmpPath, { force: true, });
154
- throw error;
200
+ const def = agents.find((agent) => agent.id === result.agent).def;
201
+ // Publish referenced files first; never expose a new entrypoint with missing references.
202
+ for (const file of result.files) {
203
+ if (file.relativePath !== def.filename)
204
+ writeSkillFile(file, bundle.get(file.relativePath));
155
205
  }
206
+ writeSkillFile(result.files.find((file) => file.relativePath === def.filename), def.content());
156
207
  }
157
208
  return results;
158
209
  }
@@ -1 +1 @@
1
- export declare function deepMerge<T extends Record<string, unknown>>(base: T, patch: Record<string, unknown>): T;
1
+ export declare function deepMerge<T extends object>(base: T, patch: Record<string, unknown>): T & Record<string, unknown>;
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Shared polling helpers used by every long-running wait loop (jobs, futures,
3
+ * scenarios, macros, Visual ML training, Project Git futures).
4
+ */
5
+ /** Hard ceiling for one adaptive backoff step (ms). */
6
+ export declare const MAX_POLL_INTERVAL_MS = 10000;
7
+ interface ComputeNextPollDelayMsOptions {
8
+ pollCount: number;
9
+ baseIntervalMs: number;
10
+ adaptiveEnabled: boolean;
11
+ }
12
+ /**
13
+ * Compute the next poll delay.
14
+ * When adaptive polling is enabled, the interval doubles every 3 polls,
15
+ * capped at MAX_POLL_INTERVAL_MS (or baseIntervalMs if it's larger).
16
+ */
17
+ export declare function computeNextPollDelayMs({ pollCount, baseIntervalMs, adaptiveEnabled, }: ComputeNextPollDelayMsOptions): number;
18
+ /** Distinguish an exhausted wait deadline from an earlier request timeout. */
19
+ export declare function isRequestDeadlineError(error: unknown, deadlineAt: number): boolean;
20
+ export {};
@@ -0,0 +1,27 @@
1
+ import { DataikuError, } from "../errors.js";
2
+ /**
3
+ * Shared polling helpers used by every long-running wait loop (jobs, futures,
4
+ * scenarios, macros, Visual ML training, Project Git futures).
5
+ */
6
+ /** Hard ceiling for one adaptive backoff step (ms). */
7
+ export const MAX_POLL_INTERVAL_MS = 10_000;
8
+ /**
9
+ * Compute the next poll delay.
10
+ * When adaptive polling is enabled, the interval doubles every 3 polls,
11
+ * capped at MAX_POLL_INTERVAL_MS (or baseIntervalMs if it's larger).
12
+ */
13
+ export function computeNextPollDelayMs({ pollCount, baseIntervalMs, adaptiveEnabled, }) {
14
+ if (!adaptiveEnabled) {
15
+ return baseIntervalMs;
16
+ }
17
+ const step = Math.max(0, Math.floor((pollCount - 1) / 3));
18
+ const interval = baseIntervalMs * 2 ** step;
19
+ return Math.min(interval, Math.max(baseIntervalMs, MAX_POLL_INTERVAL_MS));
20
+ }
21
+ /** Distinguish an exhausted wait deadline from an earlier request timeout. */
22
+ export function isRequestDeadlineError(error, deadlineAt) {
23
+ return Date.now() >= deadlineAt
24
+ && error instanceof DataikuError
25
+ && error.status === 0
26
+ && (error.retry?.timedOut === true || error.statusText === "Request Timeout");
27
+ }
@@ -0,0 +1,2 @@
1
+ /** Stream with backpressure; publish only a complete download, preserving existing output on failure. */
2
+ export declare function writeResponseToFile(path: string, response: Response, permissions?: "private" | "preserve"): Promise<number>;
@@ -0,0 +1,34 @@
1
+ import { randomUUID, } from "node:crypto";
2
+ import { createWriteStream, } from "node:fs";
3
+ import { chmod, rename, rm, stat, } from "node:fs/promises";
4
+ import { basename, dirname, join, } from "node:path";
5
+ import { Readable, } from "node:stream";
6
+ import { pipeline, } from "node:stream/promises";
7
+ /** Stream with backpressure; publish only a complete download, preserving existing output on failure. */
8
+ export async function writeResponseToFile(path, response, permissions = "private") {
9
+ let mode;
10
+ if (permissions === "preserve") {
11
+ try {
12
+ mode = (await stat(path)).mode & 0o777;
13
+ }
14
+ catch (error) {
15
+ if (error.code !== "ENOENT")
16
+ throw error;
17
+ mode = 0o666 & ~process.umask();
18
+ }
19
+ }
20
+ const input = Readable.from(response.body, { objectMode: false, });
21
+ const temporaryPath = join(dirname(path), `.${basename(path)}.tmp-${randomUUID()}`);
22
+ const output = createWriteStream(temporaryPath, { flags: "wx", mode: 0o600, });
23
+ try {
24
+ await pipeline(input, output);
25
+ // Keep partial contents private; restore publication permissions only after completion.
26
+ if (mode !== undefined)
27
+ await chmod(temporaryPath, mode);
28
+ await rename(temporaryPath, path);
29
+ return output.bytesWritten;
30
+ }
31
+ finally {
32
+ await rm(temporaryPath, { force: true, });
33
+ }
34
+ }
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Shared recursive secret sanitizer for CLI output and error surfaces.
3
+ *
4
+ * Walks any JSON-like value and:
5
+ * - replaces values under sensitive keys (per-domain key table) with `[redacted]`;
6
+ * - replaces exact occurrences of known secret values anywhere in strings;
7
+ * - optionally redacts userinfo embedded in HTTP(S) URL authorities
8
+ * (`https://user:pass@host/...` -> `https://[redacted]@host/...`).
9
+ *
10
+ * The SDK resource layer forwards values verbatim to DSS over TLS; sanitization
11
+ * is a CLI presentation concern and must never leak secret material instead.
12
+ */
13
+ /** Marker replacing every redacted value or secret occurrence. */
14
+ export declare const SECRET_REDACTED = "[redacted]";
15
+ /** Sensitive keys are matched after stripping `-`/`_` and lowercasing. */
16
+ export declare function normalizeSecretKey(key: string): string;
17
+ export interface SecretSanitizeOptions {
18
+ /**
19
+ * Per-domain table of sensitive keys (normalized form -> true). Policies
20
+ * deliberately differ between domains; never merge them.
21
+ */
22
+ sensitiveKeys: Record<string, true>;
23
+ /**
24
+ * Optional extra predicate over normalized keys for key families a flat
25
+ * table cannot express (e.g. the user `secrets` array).
26
+ */
27
+ isSensitiveKey?: (normalizedKey: string) => boolean;
28
+ /** Exact secret values to replace everywhere in strings. */
29
+ secrets?: string[];
30
+ /** Also redact userinfo embedded in HTTP(S) URL authorities. */
31
+ redactUrlUserinfo?: boolean;
32
+ }
33
+ /**
34
+ * Replace every exact occurrence of each secret so echoed errors cannot leak
35
+ * it. Empty secrets are skipped (an empty needle would corrupt every string).
36
+ */
37
+ export declare function replaceSecrets(text: string, secrets: readonly string[]): string;
38
+ /**
39
+ * Redact the userinfo of every HTTP(S) URL in a string. DSS may contain legacy
40
+ * remotes with credentials in the URL, and Git error text can echo them.
41
+ */
42
+ export declare function redactUrlUserinfo(text: string): string;
43
+ /**
44
+ * Recursively sanitize `value`: strings lose exact secret occurrences (and
45
+ * URL userinfo when enabled), objects redact values under sensitive keys and
46
+ * recurse, arrays recurse. Non-string scalars pass through unchanged.
47
+ */
48
+ export declare function sanitizeSecrets<T>(value: T, options: SecretSanitizeOptions): T;
49
+ /**
50
+ * Scrub secret material from an error's message, stack, and string body.
51
+ * `DataikuError.message` is built at construction, so all three carriers need
52
+ * the same string pass as output values.
53
+ */
54
+ export declare function sanitizeErrorSecrets(error: unknown, options: SecretSanitizeOptions): unknown;
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Shared recursive secret sanitizer for CLI output and error surfaces.
3
+ *
4
+ * Walks any JSON-like value and:
5
+ * - replaces values under sensitive keys (per-domain key table) with `[redacted]`;
6
+ * - replaces exact occurrences of known secret values anywhere in strings;
7
+ * - optionally redacts userinfo embedded in HTTP(S) URL authorities
8
+ * (`https://user:pass@host/...` -> `https://[redacted]@host/...`).
9
+ *
10
+ * The SDK resource layer forwards values verbatim to DSS over TLS; sanitization
11
+ * is a CLI presentation concern and must never leak secret material instead.
12
+ */
13
+ /** Marker replacing every redacted value or secret occurrence. */
14
+ export const SECRET_REDACTED = "[redacted]";
15
+ /** Sensitive keys are matched after stripping `-`/`_` and lowercasing. */
16
+ export function normalizeSecretKey(key) {
17
+ return key.replace(/[-_]/g, "").toLowerCase();
18
+ }
19
+ /**
20
+ * Replace every exact occurrence of each secret so echoed errors cannot leak
21
+ * it. Empty secrets are skipped (an empty needle would corrupt every string).
22
+ */
23
+ export function replaceSecrets(text, secrets) {
24
+ let result = text;
25
+ for (const secret of secrets) {
26
+ if (secret !== "" && secret !== undefined && secret !== null) {
27
+ result = result.split(secret).join(SECRET_REDACTED);
28
+ }
29
+ }
30
+ return result;
31
+ }
32
+ /**
33
+ * Redact the userinfo of every HTTP(S) URL in a string. DSS may contain legacy
34
+ * remotes with credentials in the URL, and Git error text can echo them.
35
+ */
36
+ export function redactUrlUserinfo(text) {
37
+ return text.replace(/https?:[\\/]{1,2}[^\s"'<>]+/giu, (url) => {
38
+ const schemeEnd = url.indexOf(":") + 1;
39
+ let authorityStart = schemeEnd;
40
+ while (url[authorityStart] === "/" || url[authorityStart] === "\\")
41
+ authorityStart++;
42
+ const slash = url.slice(authorityStart).search(/[\\/]/u);
43
+ const authorityEnd = slash === -1 ? url.length : authorityStart + slash;
44
+ const at = url.lastIndexOf("@", authorityEnd - 1);
45
+ if (at < authorityStart)
46
+ return url;
47
+ return `${url.slice(0, authorityStart)}${SECRET_REDACTED}@${url.slice(at + 1)}`;
48
+ });
49
+ }
50
+ /**
51
+ * Recursively sanitize `value`: strings lose exact secret occurrences (and
52
+ * URL userinfo when enabled), objects redact values under sensitive keys and
53
+ * recurse, arrays recurse. Non-string scalars pass through unchanged.
54
+ */
55
+ export function sanitizeSecrets(value, options) {
56
+ const { secrets = [], } = options;
57
+ const stringPass = (text) => {
58
+ const sanitized = options.redactUrlUserinfo ? redactUrlUserinfo(text) : text;
59
+ return replaceSecrets(sanitized, secrets);
60
+ };
61
+ if (typeof value === "string") {
62
+ return stringPass(value);
63
+ }
64
+ if (Array.isArray(value)) {
65
+ return value.map((item) => sanitizeSecrets(item, options));
66
+ }
67
+ if (value !== null && typeof value === "object") {
68
+ const sanitized = {};
69
+ for (const [key, item,] of Object.entries(value)) {
70
+ const normalizedKey = normalizeSecretKey(key);
71
+ sanitized[key] = options.sensitiveKeys[normalizedKey] === true
72
+ || options.isSensitiveKey?.(normalizedKey) === true
73
+ ? SECRET_REDACTED
74
+ : sanitizeSecrets(item, options);
75
+ }
76
+ return sanitized;
77
+ }
78
+ return value;
79
+ }
80
+ /**
81
+ * Scrub secret material from an error's message, stack, and string body.
82
+ * `DataikuError.message` is built at construction, so all three carriers need
83
+ * the same string pass as output values.
84
+ */
85
+ export function sanitizeErrorSecrets(error, options) {
86
+ if (!(error instanceof Error))
87
+ return error;
88
+ const stringPass = (text) => {
89
+ const sanitized = options.redactUrlUserinfo ? redactUrlUserinfo(text) : text;
90
+ return replaceSecrets(sanitized, options.secrets ?? []);
91
+ };
92
+ error.message = stringPass(error.message);
93
+ if (typeof error.stack === "string") {
94
+ error.stack = stringPass(error.stack);
95
+ }
96
+ const errorWithBody = error;
97
+ if (typeof errorWithBody.body === "string") {
98
+ errorWithBody.body = stringPass(errorWithBody.body);
99
+ }
100
+ return error;
101
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dataiku-sdk",
3
- "version": "3.1.0",
3
+ "version": "3.3.0",
4
4
  "description": "Dataiku DSS SDK and CLI for programmatic access to DSS REST APIs",
5
5
  "type": "module",
6
6
  "workspaces": [
@@ -25,13 +25,15 @@
25
25
  "build": "tsc && bun scripts/generate-build-metadata.mjs && tsc -p packages/types/tsconfig.json",
26
26
  "prepack": "bun scripts/sync-plugin-version.mjs --check && tsc && bun scripts/generate-build-metadata.mjs && tsc -p packages/types/tsconfig.json",
27
27
  "prepublishOnly": "bun scripts/sync-plugin-version.mjs --check && tsc && bun scripts/generate-build-metadata.mjs && tsc -p packages/types/tsconfig.json",
28
- "check": "tsc --noEmit && bun scripts/sync-plugin-version.mjs --check",
28
+ "check": "tsc --noEmit && tsc -p tools/oxlint/tsconfig.json && bun run check:live && bun scripts/sync-plugin-version.mjs --check",
29
29
  "version": "bun scripts/sync-plugin-version.mjs && git add plugin.json",
30
- "lint": "oxlint src/",
31
- "lint:fix": "oxlint --fix src/",
30
+ "lint": "oxlint src/ tools/oxlint/ scripts/live-suite.ts tests/live-*.ts",
31
+ "lint:fix": "oxlint --fix src/ tools/oxlint/ scripts/live-suite.ts tests/live-*.ts",
32
32
  "format": "dprint fmt",
33
33
  "format:check": "dprint check",
34
34
  "test": "bun test",
35
+ "test:live": "bun --no-env-file scripts/live-suite.ts",
36
+ "check:live": "tsc --noEmit -p tsconfig.live.json",
35
37
  "test:tokens": "bun test tests/cli/agent-token-budget.test.ts",
36
38
  "test:platform": "bun scripts/platform-smoke.mjs",
37
39
  "test:integration": "cross-env RUN_DATAIKU_INTEGRATION=1 bun test tests/integration-playground.test.ts",
@@ -40,11 +42,12 @@
40
42
  "test:integration:rigorous:mutating": "cross-env RUN_DATAIKU_INTEGRATION=1 RUN_DATAIKU_INTEGRATION_MUTATING=1 bun test tests/integration-rigorous.test.ts"
41
43
  },
42
44
  "devDependencies": {
45
+ "@oxlint/plugins": "1.81.0",
43
46
  "@types/bun": "^1.4.0",
44
47
  "cross-env": "^10.1.0",
45
48
  "dprint": "^0.57.0",
46
49
  "js-tiktoken": "1.0.21",
47
- "oxlint": "^1.81.0",
50
+ "oxlint": "1.81.0",
48
51
  "typescript": "^7.0.2",
49
52
  "typescript-language-server": "6.0.0",
50
53
  "typescript-language-service": "npm:typescript@5.9.3"